Ticket #2581: aspectRatio.patch

File aspectRatio.patch, 10.8 KB (added by wagspat@…, 14 years ago)

example patch that implements aspect ratio setting on mpeg4 transcoders

  • libs/libmythtv/recordingprofile.cpp

    diff -ur mythtv-0.20/libs/libmythtv/recordingprofile.cpp mythtv-0.20.modified/libs/libmythtv/recordingprofile.cpp
    old new  
    434434    };
    435435};
    436436
     437class MPEG4AspectRatio: public CodecParam, public ComboBoxSetting {
     438public:
     439   MPEG4AspectRatio(const RecordingProfile& parent):
     440        CodecParam(parent, "mpeg4aspectratio") {
     441        setLabel(QObject::tr("Aspect Ratio"));
     442        addSelection("Leave", "Leave");
     443        addSelection("4:3", "4:3");
     444        addSelection("16:9", "16:9");
     445        setValue(0);
     446        setHelpText(QObject::tr("Sets the aspect ratio of transcoded files"));
     447    };
     448};
     449
     450
    437451class EncodingThreadCount: public CodecParam, public SliderSetting {
    438452public:
    439453    EncodingThreadCount(const RecordingProfile& parent):
     
    581595        params->addChild(new MPEG4MinQuality(parent));
    582596        params->addChild(new MPEG4QualDiff(parent));
    583597        params->addChild(new MPEG4ScaleBitrate(parent));
     598        params->addChild(new MPEG4AspectRatio(parent));
    584599
    585600        HorizontalConfigurationGroup *hq;
    586601        hq = new HorizontalConfigurationGroup(false, false);
  • programs/mythfrontend/playbackbox.cpp

    Only in mythtv-0.20.modified/programs/mythbackend: version.cpp
    diff -ur mythtv-0.20/programs/mythfrontend/playbackbox.cpp mythtv-0.20.modified/programs/mythfrontend/playbackbox.cpp
    old new  
    27332733                     SLOT(changeProfileAndTranscodeMedium()));
    27342734    popup->addButton(tr("Low Quality"), this,
    27352735                     SLOT(changeProfileAndTranscodeLow()));
    2736 
    27372736    popup->ShowPopup(this, SLOT(doCancel()));
    27382737    defaultButton->setFocus();
    27392738   
  • programs/mythtranscode/transcode.cpp

    Only in mythtv-0.20.modified/programs/mythfrontend: version.cpp
    Only in mythtv-0.20.modified/programs/mythtranscode: orig
    diff -ur mythtv-0.20/programs/mythtranscode/transcode.cpp mythtv-0.20.modified/programs/mythtranscode/transcode.cpp
    old new  
    383383
    384384    int video_width = nvp->GetVideoWidth();
    385385    int video_height = nvp->GetVideoHeight();
     386     
     387    if (video_height == 1088) {
     388       VERBOSE(VB_IMPORTANT, QString("Unlikely the video height really is 1088, using hacks..."));
     389    }
     390
    386391    float video_aspect = nvp->GetVideoAspect();
     392    VERBOSE(VB_IMPORTANT, QString("Transcode: aspect ratio: %1").arg(video_aspect));
     393
    387394    float video_frame_rate = nvp->GetFrameRate();
    388395    int newWidth = video_width;
    389396    int newHeight = video_height;
    390397
     398    /* this allows transcoders to have fixed aspect ratios */
     399    float newAspect = video_aspect;
     400    /* these elements control the on screen cropping */
     401    int crop_top, crop_bottom, crop_left, crop_right;
     402    crop_top = crop_bottom = crop_left = crop_right = 0;
     403
    391404    kfa_table = new QPtrList<struct kfatable_entry>;
    392405
    393406    if (fifodir == NULL)
     
    415428        }
    416429        else if (profile.byName("transcoderesize")->getValue().toInt())
    417430        {
     431            int fudge1080 = (video_height == 1088 ? 8 : 0);
     432
    418433            nvp->SetVideoFilters(vidfilters);
    419434            newWidth = profile.byName("width")->getValue().toInt();
    420435            newHeight = profile.byName("height")->getValue().toInt();
    421436
    422437            // If height or width are 0, then we need to calculate them
    423438            if (newHeight == 0 && newWidth > 0)
    424                 newHeight = (int)(1.0 * newWidth * video_height / video_width);
     439                newHeight = (int)(1.0 * newWidth * (video_height-fudge1080) / video_width);
    425440            else if (newWidth == 0 && newHeight > 0)
    426                 newWidth = (int)(1.0 * newHeight * video_width / video_height);
     441                newWidth = (int)(1.0 * newHeight * video_width / (video_height-fudge1080));
    427442            else if (newWidth == 0 && newHeight == 0)
    428443            {
    429444                newHeight = 480;
    430                 newWidth = (int)(1.0 * 480 * video_width / video_height);
     445                newWidth = (int)(1.0 * 480 * video_width / (video_height-fudge1080));
    431446                if (newWidth > 640)
    432447                {
    433448                    newWidth = 640;
    434                     newHeight = (int)(1.0 * 640 * video_height / video_width);
     449                    newHeight = (int)(1.0 * 640 * (video_height-fudge1080) / video_width);
     450                }
     451            }
     452            /* hack by Patrick Wagstrom to ensure that aspect ratios are enforced
     453             * if this is set to 43 then we crop the picture to fit the aspect ratio */
     454            if (vidsetting == "MPEG-4")
     455            {
     456               const Setting* setting = profile.byName("mpeg4aspectratio");
     457                if (setting) {
     458                    if (setting->getValue() == "4:3") {
     459                        VERBOSE(VB_IMPORTANT, QString("Transcode: Got a 4:3 setting"));
     460                        newAspect = 1.333333333333;
     461                    } else if (setting->getValue() == "16:9") {
     462                        VERBOSE(VB_IMPORTANT, QString("Transcode: Got a 16:9 setting"));
     463                        newAspect = 1.777777777777;
     464                    } else if (setting->getValue() == "Leave") {
     465                        VERBOSE(VB_IMPORTANT, QString("Transcode: got a leave setting"));
     466                    } else {
     467                        VERBOSE(VB_IMPORTANT, QString("Transcode: unable to get aspect ratio"));
     468                    }
     469                    /* support for cropping... */
     470                    if (abs(newAspect - video_aspect) > 0.01) {
     471                        if (abs(video_aspect - 1.77777) < 0.01) {
     472                            /* working with 16:9 source -- assume the height is correct */
     473                            crop_left = (int)(video_width - (video_height * newAspect))/2;
     474                            crop_right = crop_left;
     475                            newWidth = (int)(newHeight * newAspect);
     476                            /* while we're at it, kill the noise on the top of th screen too */
     477                            crop_top = 8;
     478                        } else if (abs(video_aspect - 1.33333) < 0.01) {
     479                            /* working with 4:3 source -- assume the width is correct */
     480                            crop_top = (int)(video_height - (video_width / newAspect))/2;
     481                            crop_bottom = crop_top;
     482                            newHeight = (int)(newWidth / newAspect);
     483                        }
     484                    }
     485                } else {
     486                    VERBOSE(VB_IMPORTANT, QString("Transcode: unable to get aspect ratio"));
    435487                }
    436488            }
    437489
     
    445497            VERBOSE(VB_IMPORTANT, QString("Resizing from %1x%2 to %3x%4")
    446498                    .arg(video_width).arg(video_height)
    447499                    .arg(newWidth).arg(newHeight));
     500            VERBOSE(VB_IMPORTANT, QString("Crop Settings %1 %2 %3 %4")
     501                    .arg(crop_left).arg(crop_right)
     502                    .arg(crop_top).arg(crop_bottom));
    448503        }
    449504        else  // lossy and no resize
    450505            nvp->SetVideoFilters(vidfilters);
     
    469524            SetProfileOption(profile, "mpeg4qualdiff");
    470525            SetProfileOption(profile, "mpeg4optionvhq");
    471526            SetProfileOption(profile, "mpeg4option4mv");
    472             nvr->SetupAVCodec();
     527           nvr->SetupAVCodec();
    473528        }
    474529        else if (vidsetting == "RTjpeg")
    475530        {
     
    504559        nvr->AudioInit(true);
    505560
    506561        nvr->SetFrameRate(video_frame_rate);
    507         nvr->SetVideoAspect(video_aspect);
     562        /* update the aspect to the new video aspect */
     563        nvr->SetVideoAspect(newAspect);
    508564        nvr->SetTranscoding(true);
    509565
    510566        outRingBuffer = new RingBuffer(outputname, true, false);
     
    786842                                   video_width, video_height);
    787843                    avpicture_fill(&imageOut, frame.buf, PIX_FMT_YUV420P,
    788844                                   newWidth, newHeight);
    789                     scontext = img_resample_init(newWidth, newHeight,
    790                                                  video_width, video_height);
     845
     846                    /* fix for problems with 1088 high video frames */
     847                    if (video_height == 1088 && crop_bottom < 8) {
     848                        crop_bottom = 8;
     849                    }
     850                    scontext = img_resample_full_init(newWidth, newHeight,
     851                                                      video_width, video_height,
     852                                                      crop_top,crop_bottom,crop_left,crop_right,
     853                                                      0,0,0,0);
    791854                    img_resample(scontext, &imageOut, &imageIn);
    792855                    img_resample_close(scontext);
    793856                }
     
    806869                    (frame.timecode - lasttimecode - (int)vidFrameTime);
    807870            }
    808871
    809             if (video_aspect != nvp->GetVideoAspect())
     872            if (newAspect != nvp->GetVideoAspect())
    810873            {
    811                 video_aspect = nvp->GetVideoAspect();
    812                 nvr->SetNewVideoParams(video_aspect);
     874                // used to check video aspect
     875                // video_aspect = nvp->GetVideoAspect();
     876                nvr->SetNewVideoParams(newAspect);
    813877            }
    814878
    815879            if (video_width != nvp->GetVideoWidth() ||
     
    820884                VERBOSE(VB_IMPORTANT, QString("Resizing from %1x%2 to %3x%4")
    821885                        .arg(video_width).arg(video_height)
    822886                        .arg(newWidth).arg(newHeight));
    823             }
     887           }
    824888
    825889            if ((video_width == newWidth) && (video_height == newHeight))
    826890            {
     
    832896                               video_width, video_height);
    833897                avpicture_fill(&imageOut, frame.buf, PIX_FMT_YUV420P,
    834898                               newWidth, newHeight);
    835                 scontext = img_resample_init(newWidth, newHeight,
    836                                              video_width, video_height);
     899 
     900                /* fix for problems with 1088 high video frames */
     901                if (video_height == 1088 && crop_bottom < 8) {
     902                    crop_bottom = 8;
     903                }
     904                scontext = img_resample_full_init(newWidth, newHeight,
     905                                                  video_width, video_height,
     906                                                  crop_top,crop_bottom,crop_left,crop_right,
     907                                                  0,0,0,0);
    837908                img_resample(scontext, &imageOut, &imageIn);
    838909                img_resample_close(scontext);
    839910            }