Ticket #2581: aspectRatio-0-20-2.a.patch

File aspectRatio-0-20-2.a.patch, 10.1 KB (added by patrick@…, 5 years ago)

updated version of the patch that adequately deals with non-square pixel videos

  • libs/libmythtv/recordingprofile.cpp

     
    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/mythtranscode/transcode.cpp

     
    388388    int newWidth = video_width; 
    389389    int newHeight = video_height; 
    390390 
     391     
     392    if (video_height == 1088) { 
     393       VERBOSE(VB_IMPORTANT, "Found video height of 1088.  This is unusual and " 
     394               "more than likely the video is actually 1080 so mythtranscode " 
     395               "will treat it as such."); 
     396    } 
     397    VERBOSE(VB_IMPORTANT, QString("Transcode: current aspect ratio: %1").arg(video_aspect)); 
     398     
     399    /* this allows transcoders to have fixed aspect ratios */ 
     400    float newAspect = video_aspect; 
     401    /* these elements control the on screen cropping */ 
     402    int crop_top, crop_bottom, crop_left, crop_right; 
     403    crop_top = crop_bottom = crop_left = crop_right = 0; 
     404     
    391405    kfa_table = new QPtrList<struct kfatable_entry>; 
    392  
    393406    if (fifodir == NULL) 
    394407    { 
    395408        if (!GetProfile(profileName, encodingType)) { 
     
    415428        } 
    416429        else if (profile.byName("transcoderesize")->getValue().toInt()) 
    417430        { 
     431                int actualHeight = (video_height == 1088 ? 1080 : video_height); 
     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 * actualHeight / 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 / actualHeight); 
    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 / actualHeight); 
    431446                if (newWidth > 640) 
    432447                { 
    433448                    newWidth = 640; 
    434                     newHeight = (int)(1.0 * 640 * video_height / video_width); 
     449                    newHeight = (int)(1.0 * 640 * actualHeight / video_width); 
    435450                } 
    436451            } 
    437  
     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("Transcoder calls for a 4:3 aspect ratio")); 
     460                        newAspect = 1.333333333333; 
     461                    } else if (setting->getValue() == "16:9") { 
     462                        VERBOSE(VB_IMPORTANT, QString("Transcoder calls for a 16:9 aspect ratio")); 
     463                        newAspect = 1.777777777777; 
     464                    } else if (setting->getValue() == "Leave") { 
     465                        VERBOSE(VB_IMPORTANT, QString("Transcoder leaves aspect ratio unchanged")); 
     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                        /* calculate the actual pixel ratio for videos, needed 
     472                         * when encoded without square pixels, such as 720x480 
     473                         * NTSC captures */ 
     474                        float pixelRatio = float(video_width)/float(video_height)/video_aspect; 
     475                        /* scale the aspect ratio by the pixel ratio for the new sizes */ 
     476                        float newAspectScaling = newAspect * pixelRatio; 
     477                        if (abs(video_aspect - 1.77777) < 0.01) { 
     478                            /* working with 16:9 source -- assume the height is correct */ 
     479                            newWidth = (int)(newHeight * newAspectScaling); 
     480                            crop_left = (int)(video_width - newWidth)/2; 
     481                            crop_right = crop_left; 
     482                            /* while we're at it, kill the noise on the top of th screen too */ 
     483                            crop_top = crop_top + 8; 
     484                            VERBOSE(VB_IMPORTANT, QString("Transcode: removing top 8 pixels to get rid of garbage from Comcast"));                             
     485                        } else if (abs(video_aspect - 1.33333) < 0.01) { 
     486                            /* working with 4:3 source -- assume the width is correct */ 
     487                            newHeight = (int)(newWidth / newAspectScaling); 
     488                            crop_top = (int)(video_height - newHeight)/2; 
     489                            crop_bottom = crop_top; 
     490                        } else { 
     491                            VERBOSE(VB_IMPORTANT, QString("Transcode: got a video with unknown aspect ratio %1").arg(video_aspect)); 
     492                        } 
     493                    } 
     494                } else { 
     495                    VERBOSE(VB_IMPORTANT, QString("Transcode: unable to get aspect ratio")); 
     496                } 
     497            } 
     498             
    438499            if (encodingType.left(4).lower() == "mpeg") 
    439500            { 
    440501                // make sure dimensions are valid for MPEG codecs 
     
    445506            VERBOSE(VB_IMPORTANT, QString("Resizing from %1x%2 to %3x%4") 
    446507                    .arg(video_width).arg(video_height) 
    447508                    .arg(newWidth).arg(newHeight)); 
     509            VERBOSE(VB_IMPORTANT, QString("Crop Settings %1 %2 %3 %4") 
     510                    .arg(crop_left).arg(crop_right) 
     511                    .arg(crop_top).arg(crop_bottom)); 
    448512        } 
    449513        else  // lossy and no resize 
    450514            nvp->SetVideoFilters(vidfilters); 
     
    504568        nvr->AudioInit(true); 
    505569 
    506570        nvr->SetFrameRate(video_frame_rate); 
    507         nvr->SetVideoAspect(video_aspect); 
     571        /* update the aspect to the new video aspect */ 
     572        nvr->SetVideoAspect(newAspect); 
    508573        nvr->SetTranscoding(true); 
    509574 
    510575        outRingBuffer = new RingBuffer(outputname, true, false); 
     
    785850                    avpicture_fill(&imageIn, lastDecode->buf, PIX_FMT_YUV420P, 
    786851                                   video_width, video_height); 
    787852                    avpicture_fill(&imageOut, frame.buf, PIX_FMT_YUV420P, 
    788                                    newWidth, newHeight); 
    789                     scontext = img_resample_init(newWidth, newHeight, 
    790                                                  video_width, video_height); 
     853                                   newWidth, newHeight);                     
     854                    if (video_height == 1088 && crop_bottom < 8) { 
     855                        crop_bottom = 8; 
     856                    } 
     857                    scontext = img_resample_full_init(newWidth, newHeight, 
     858                                video_width, video_height, 
     859                                crop_top, crop_bottom, crop_left, crop_right, 
     860                                0,0,0,0); 
     861                     
    791862                    img_resample(scontext, &imageOut, &imageIn); 
    792863                    img_resample_close(scontext); 
    793864                } 
     
    806877                    (frame.timecode - lasttimecode - (int)vidFrameTime); 
    807878            } 
    808879 
    809             if (video_aspect != nvp->GetVideoAspect()) 
     880            if (newAspect != nvp->GetVideoAspect()) 
    810881            { 
    811                 video_aspect = nvp->GetVideoAspect(); 
    812                 nvr->SetNewVideoParams(video_aspect); 
     882                // used to check video aspect 
     883                // video_aspect = nvp->GetVideoAspect(); 
     884                nvr->SetNewVideoParams(newAspect); 
    813885            } 
    814886 
    815887            if (video_width != nvp->GetVideoWidth() ||  
     
    832904                               video_width, video_height); 
    833905                avpicture_fill(&imageOut, frame.buf, PIX_FMT_YUV420P, 
    834906                               newWidth, newHeight); 
    835                 scontext = img_resample_init(newWidth, newHeight, 
    836                                              video_width, video_height); 
     907                if (video_height != 1088) { 
     908                    scontext = img_resample_init(newWidth, newHeight, 
     909                                                 video_width, video_height); 
     910                } 
     911                else 
     912                { 
     913                    scontext = img_resample_full_init(newWidth, newHeight, 
     914                                                      video_width, video_height, 
     915                                                      0,8,0,0,0,0,0,0); 
     916                } 
    837917                img_resample(scontext, &imageOut, &imageIn); 
    838918                img_resample_close(scontext); 
    839919            }