Index: libs/libmythtv/recordingprofile.cpp
===================================================================
--- libs/libmythtv/recordingprofile.cpp	(revision 21446)
+++ libs/libmythtv/recordingprofile.cpp	(working copy)
@@ -571,6 +571,34 @@
     };
 };
 
+class MPEG4AspectRatio: public ComboBoxSetting, public CodecParamStorage {
+public:
+   MPEG4AspectRatio(const RecordingProfile& parent):
+        ComboBoxSetting(this),
+        CodecParamStorage(this, parent, "mpeg4aspectratio") {
+        setLabel(QObject::tr("Aspect Ratio"));
+        addSelection(QObject::tr("Original", "Original"));
+        addSelection(QObject::tr("Crop to 4:3", "4:3"));
+        addSelection(QObject::tr("Crop to 16:9", "16:9"));
+        setValue("Original");
+        setHelpText(QObject::tr("Crop transcoded files to the indicated "
+                                "aspect ratio"));
+    };
+};
+
+class MPEG4DeInterlace: public ComboBoxSetting, public CodecParamStorage {
+public:
+   MPEG4DeInterlace(const RecordingProfile& parent):
+        ComboBoxSetting(this),
+        CodecParamStorage(this, parent, "mpeg4deinterlace") {
+        setLabel(QObject::tr("DeInterlace"));
+        addSelection(QObject::tr("No", "0"));
+        addSelection(QObject::tr("Yes", "1"));
+        setValue("0");
+        setHelpText(QObject::tr("DeInterlace video when resizing"));
+    };
+};
+
 class MPEG4QualDiff : public SliderSetting, public CodecParamStorage
 {
   public:
@@ -822,12 +850,27 @@
 
         params = new VerticalConfigurationGroup(false);
         params->setLabel(QObject::tr("MPEG-4 Parameters"));
-        params->addChild(new MPEG4bitrate(parent));
-        params->addChild(new MPEG4MaxQuality(parent));
-        params->addChild(new MPEG4MinQuality(parent));
+
+        HorizontalConfigurationGroup *hbr;
+        hbr = new HorizontalConfigurationGroup(false, false);
+        hbr->addChild(new MPEG4bitrate(parent));
+        hbr->addChild(new ScaleBitrate(parent));
+        params->addChild(hbr);
+
+        HorizontalConfigurationGroup *hmmq;
+        hmmq = new HorizontalConfigurationGroup(false, false);
+        hmmq->addChild(new MPEG4MaxQuality(parent));
+        hmmq->addChild(new MPEG4MinQuality(parent));
+        params->addChild(hmmq);
+
         params->addChild(new MPEG4QualDiff(parent));
-        params->addChild(new ScaleBitrate(parent));
 
+        HorizontalConfigurationGroup *hasp;
+        hasp = new HorizontalConfigurationGroup(false, false);
+        hasp->addChild(new MPEG4AspectRatio(parent));
+        hasp->addChild(new MPEG4DeInterlace(parent));
+        params->addChild(hasp);
+
         HorizontalConfigurationGroup *hq;
         hq = new HorizontalConfigurationGroup(false, false);
         hq->addChild(new MPEG4OptionVHQ(parent));
Index: programs/mythtranscode/transcode.cpp
===================================================================
--- programs/mythtranscode/transcode.cpp	(revision 21446)
+++ programs/mythtranscode/transcode.cpp	(working copy)
@@ -32,11 +32,6 @@
 #include "mythdbcon.h"
 
 
-extern "C" {
-#include "libavcodec/avcodec.h"
-#include "libswscale/swscale.h"
-}
-
 #define LOC QString("Transcode: ")
 #define LOC_ERR QString("Transcode, Error: ")
 
@@ -248,7 +243,9 @@
     fifow(NULL),
     kfa_table(NULL),
     showprogress(false),
-    recorderOptions("")   
+    recorderOptions(""),
+    m_deinterlace(false),
+    m_scontext(NULL)
 {
 }
 
@@ -268,6 +265,11 @@
         delete fifow;
     if (kfa_table)
         delete kfa_table;
+
+    if (m_deinterlace)
+        avpicture_free(&m_imageDeInt);
+    if (m_scontext)
+        sws_freeContext(m_scontext);
 }
 void Transcode::ReencoderAddKFA(long curframe, long lastkey, long num_keyframes)
 {
@@ -333,7 +335,7 @@
         // If a bad profile is specified, there will be trouble
         if (isNum && profileID > 0)
             profile.loadByID(profileID);
-        else
+        else if (!profile.loadByGroup(profileName, "Transcoders"))
         {
             VERBOSE(VB_IMPORTANT, QString("Couldn't find profile #: %1").
                     arg(profileName));
@@ -379,6 +381,58 @@
   nvr->WriteText(buf, len, timecode, pagenr);
 }
 
+void Transcode::EncodeFrame(unsigned char *srcBuf, int srcWidth, int srcHeight,
+                            unsigned char *dstBuf, int dstWidth, int dstHeight,
+                            int cr_top, int cr_bottom,
+                            int cr_left, int cr_right)
+{
+    avpicture_fill(&m_imageIn, srcBuf, PIX_FMT_YUV420P, srcWidth, srcHeight);
+    avpicture_fill(&m_imageOut, dstBuf, PIX_FMT_YUV420P, dstWidth, dstHeight);
+
+    int bottomBand = (srcHeight == 1088) ? 8 : 0;
+    if (cr_top || cr_bottom || cr_left || cr_right)
+    {
+        AVPicture *cropSrc = &m_imageIn;
+        if (m_deinterlace)
+        {
+            cropSrc = &m_imageDeInt;
+            avpicture_deinterlace(&m_imageDeInt, &m_imageIn, PIX_FMT_YUV420P,
+                                  srcWidth, srcHeight);
+        }
+
+        av_picture_crop(&m_imageCrop, cropSrc,
+                        PIX_FMT_YUV420P, cr_top, cr_left);
+
+        m_scontext = sws_getCachedContext(m_scontext,
+                       srcWidth - cr_left - cr_right,
+                       srcHeight - cr_top - cr_bottom, PIX_FMT_YUV420P,
+                       dstWidth, dstHeight, PIX_FMT_YUV420P,
+                       SWS_FAST_BILINEAR, NULL, NULL, NULL);
+        sws_scale(m_scontext, m_imageCrop.data, m_imageCrop.linesize, 0,
+              srcHeight - bottomBand - cr_top - cr_bottom,
+              m_imageOut.data, m_imageOut.linesize);
+    }
+    else
+    {
+
+        m_scontext = sws_getCachedContext(m_scontext, srcWidth, srcHeight,
+                                          PIX_FMT_YUV420P, dstWidth, dstHeight,
+                                          PIX_FMT_YUV420P, SWS_FAST_BILINEAR,
+                                          NULL, NULL, NULL);
+
+        AVPicture *scaleSrc = &m_imageIn;
+        if (m_deinterlace)
+        {
+            scaleSrc = &m_imageDeInt;
+            avpicture_deinterlace(&m_imageDeInt, &m_imageIn, PIX_FMT_YUV420P,
+                                  srcWidth, srcHeight);
+        }
+
+        sws_scale(m_scontext, scaleSrc->data, scaleSrc->linesize, 0,
+                  srcHeight - bottomBand, m_imageOut.data, m_imageOut.linesize);
+    }
+}
+
 int Transcode::TranscodeFile(
     const QString &inputname,
     const QString &outputname,
@@ -486,7 +540,7 @@
     QSize buf_size = nvp->GetVideoBufferSize();
     int video_width = buf_size.width();
     int video_height = buf_size.height();
-     
+
     if (video_height == 1088) {
        VERBOSE(VB_IMPORTANT, "Found video height of 1088.  This is unusual and "
                "more than likely the video is actually 1080 so mythtranscode "
@@ -498,6 +552,19 @@
     int newWidth = video_width;
     int newHeight = video_height;
 
+    video_aspect = 1.33333333;
+
+    VERBOSE(VB_IMPORTANT, QString("Transcode: current aspect ratio: %1")
+                                  .arg(video_aspect));
+
+
+    float newAspect  = video_aspect;
+    float oldAspect  = video_aspect;
+    int crop_top     = 0;
+    int crop_bottom  = 0;
+    int crop_left    = 0;
+    int crop_right   = 0;
+
     kfa_table = new vector<struct kfatable_entry>;
 
     if (fifodir.isEmpty())
@@ -553,6 +620,9 @@
             newWidth = get_int_option(profile, "width");
             newHeight = get_int_option(profile, "height");
 
+            int profWidth = newWidth;
+            int profHeight = newHeight;
+
             // If height or width are 0, then we need to calculate them
             if (newHeight == 0 && newWidth > 0)
                 newHeight = (int)(1.0 * newWidth * actualHeight / video_width);
@@ -569,6 +639,69 @@
                 }
             }
 
+            if (vidsetting == "MPEG-4")
+            {
+                const Setting* setting = profile.byName("mpeg4aspectratio");
+                if (setting)
+                {
+                    if (setting->getValue() == "4:3") {
+                        VERBOSE(VB_IMPORTANT, QString(
+                                "Transcoder calls for a 4:3 aspect ratio"));
+                        newAspect = 1.333333333333;
+                    } else if (setting->getValue() == "16:9") {
+                        VERBOSE(VB_IMPORTANT, QString(
+                                "Transcoder calls for a 16:9 aspect ratio"));
+                        newAspect = 1.777777777777;
+                    } else if (setting->getValue() == "Original") {
+                        VERBOSE(VB_IMPORTANT, QString(
+                                "Transcoder leaving aspect ratio unchanged"));
+                    } else {
+                        VERBOSE(VB_IMPORTANT, QString(
+                                "Transcode unable to determine aspect ratio"));
+                    }
+
+                    // if aspect ratios differ then crop the output
+                    if (abs(newAspect - oldAspect) > 0.001) {
+                        // calculate the actual pixel ratio for videos, needed
+                        // when encoded without square pixels, such as 720x480
+                        // NTSC captures
+                        float pixelRatio =
+                            float(video_width)/float(video_height)/oldAspect;
+
+                        // scale the aspect ratio by the pixel ratio
+                        float newAspectScaling = newAspect * pixelRatio;
+                        if (abs(oldAspect - 1.77777) < 0.001) {
+                            if (!profWidth && profHeight)
+                                newWidth = (int)(newHeight * newAspectScaling);
+                            int scaledWidth =
+                                (int)(video_height * newAspectScaling);
+                            crop_left = (int)(video_width - scaledWidth) / 2;
+                            crop_right = crop_left;
+                        } else if (abs(oldAspect - 1.33333) < 0.01) {
+                            if (profWidth && !profHeight)
+                                newHeight = (int)(newWidth / newAspectScaling);
+                            int scaledHeight =
+                                (int)(video_width / newAspectScaling);
+                            crop_top = (int)(video_height - scaledHeight) / 2;
+                            crop_bottom = crop_top;
+                        } else {
+                            VERBOSE(VB_IMPORTANT, QString("Transcode: Unknown "
+                                    "aspect ratio %1 on input video, video "
+                                    "will not be cropped.").arg(oldAspect));
+                            newAspect = oldAspect;
+                        }
+                    }
+                } else {
+                    VERBOSE(VB_IMPORTANT, QString("Transcode: Unable to "
+                            "determine aspect ratio"));
+                }
+
+                setting = profile.byName("mpeg4deinterlace");
+                if (setting)
+                    m_deinterlace = setting->getValue().toInt();
+            }
+
+
             if (encodingType.left(4).toLower() == "mpeg")
             {
                 // make sure dimensions are valid for MPEG codecs
@@ -579,6 +712,11 @@
             VERBOSE(VB_IMPORTANT, QString("Resizing from %1x%2 to %3x%4")
                     .arg(video_width).arg(video_height)
                     .arg(newWidth).arg(newHeight));
+
+            if (crop_top || crop_bottom || crop_left || crop_right)
+                VERBOSE(VB_IMPORTANT, QString("Crop Settings %1 %2 %3 %4")
+                        .arg(crop_left).arg(crop_right)
+                        .arg(crop_top).arg(crop_bottom));
         }
         else  // lossy and no resize
             nvp->SetVideoFilters(vidfilters);
@@ -593,7 +731,7 @@
         nvr->SetOption("vbiformat", gContext->GetSetting("VbiFormat"));
 
         nvr->SetFrameRate(video_frame_rate);
-        nvr->SetVideoAspect(video_aspect);
+        nvr->SetVideoAspect(newAspect);
         nvr->SetTranscoding(true);
 
         if ((vidsetting == "MPEG-4") ||
@@ -804,9 +942,11 @@
     unsigned char *newFrame = new unsigned char[frame.size];
 
     frame.buf = newFrame;
-    AVPicture imageIn, imageOut;
-    struct SwsContext  *scontext = NULL;
 
+    if (m_deinterlace)
+        avpicture_alloc(&m_imageDeInt, PIX_FMT_YUV420P,
+                        video_width, video_height);
+
     if (fifow)
         VERBOSE(VB_GENERAL, "Dumping Video and Audio data to fifos");
     else if (copyaudio)
@@ -962,10 +1102,14 @@
             if (! nvp->WriteStoredData(outRingBuffer, (did_ff == 0),
                                        timecodeOffset))
             {
-                if (video_aspect != nvp->GetVideoAspect())
+                if (oldAspect != nvp->GetVideoAspect())
                 {
                     video_aspect = nvp->GetVideoAspect();
-                    nvr->SetNewVideoParams(video_aspect);
+
+                    if (abs(video_aspect - oldAspect) < 0.001)
+                        nvr->SetNewVideoParams(newAspect);
+                    else
+                        nvr->SetNewVideoParams(video_aspect);
                 }
 
                 QSize buf_size = nvp->GetVideoBufferSize();
@@ -996,20 +1140,10 @@
                 else
                 {
                     frame.buf = newFrame;
-                    avpicture_fill(&imageIn, lastDecode->buf, PIX_FMT_YUV420P,
-                                   video_width, video_height);
-                    avpicture_fill(&imageOut, frame.buf, PIX_FMT_YUV420P,
-                                   newWidth, newHeight);
 
-                    int bottomBand = (video_height == 1088) ? 8 : 0;
-                    scontext = sws_getCachedContext(scontext, video_width,
-                                   video_height, PIX_FMT_YUV420P, newWidth,
-                                   newHeight, PIX_FMT_YUV420P,
-                                   SWS_FAST_BILINEAR, NULL, NULL, NULL);
-
-                    sws_scale(scontext, imageIn.data, imageIn.linesize, 0,
-                              video_height - bottomBand,
-                              imageOut.data, imageOut.linesize);
+                    EncodeFrame(lastDecode->buf, video_width, video_height,
+                                frame.buf, newWidth, newHeight,
+                                crop_top, crop_bottom, crop_left, crop_right);
                 }
 
                 nvr->WriteVideo(&frame, true, writekeyframe);
@@ -1029,7 +1163,10 @@
             if (video_aspect != nvp->GetVideoAspect())
             {
                 video_aspect = nvp->GetVideoAspect();
-                nvr->SetNewVideoParams(video_aspect);
+                if (abs(video_aspect - oldAspect) < 0.001)
+                    nvr->SetNewVideoParams(newAspect);
+                else
+                    nvr->SetNewVideoParams(video_aspect);
             }
 
 
@@ -1053,20 +1190,10 @@
             else
             {
                 frame.buf = newFrame;
-                avpicture_fill(&imageIn, lastDecode->buf, PIX_FMT_YUV420P,
-                               video_width, video_height);
-                avpicture_fill(&imageOut, frame.buf, PIX_FMT_YUV420P,
-                               newWidth, newHeight);
 
-                int bottomBand = (video_height == 1088) ? 8 : 0;
-                scontext = sws_getCachedContext(scontext, video_width,
-                               video_height, PIX_FMT_YUV420P, newWidth,
-                               newHeight, PIX_FMT_YUV420P,
-                               SWS_FAST_BILINEAR, NULL, NULL, NULL);
-
-                sws_scale(scontext, imageIn.data, imageIn.linesize, 0,
-                          video_height - bottomBand,
-                          imageOut.data, imageOut.linesize);
+                EncodeFrame(lastDecode->buf, video_width, video_height,
+                            frame.buf, newWidth, newHeight,
+                            crop_top, crop_bottom, crop_left, crop_right);
             }
 
             // audio is fully decoded, so we need to reencode it
@@ -1164,8 +1291,6 @@
         frame.frameNumber = 1 + (curFrameNum << 1);
     }
 
-    sws_freeContext(scontext);
-
     if (! fifow)
     {
         if (m_proginfo)
Index: programs/mythtranscode/transcode.h
===================================================================
--- programs/mythtranscode/transcode.h	(revision 21446)
+++ programs/mythtranscode/transcode.h	(working copy)
@@ -2,6 +2,11 @@
 #include "fifowriter.h"
 #include "transcodedefs.h"
 
+extern "C" {
+#include "libavcodec/avcodec.h"
+#include "libswscale/swscale.h"
+}
+
 class PlayerContext;
 class ProgramInfo;
 class NuppelVideoRecorder;
@@ -20,6 +25,9 @@
         const QString &profileName,
         bool honorCutList, bool framecontrol, int jobID,
         QString fifodir, QMap<long long, int> deleteMap);
+    void EncodeFrame(unsigned char *srcBuf, int srcWidth, int srcHeight,
+                     unsigned char *dstBuf, int dstWidth, int dstHeight,
+                     int cr_top, int cr_bottom, int cr_left, int cr_right);
     void ShowProgress(bool val) { showprogress = val; }
     void SetRecorderOptions(QString options) { recorderOptions = options; }
 
@@ -42,6 +50,13 @@
     KFATable               *kfa_table;
     bool                    showprogress;
     QString                 recorderOptions;
+
+    AVPicture               m_imageIn;
+    AVPicture               m_imageDeInt;
+    AVPicture               m_imageCrop;
+    AVPicture               m_imageOut;
+    bool                    m_deinterlace;
+    struct SwsContext      *m_scontext;
 };
 
 /* vim: set expandtab tabstop=4 shiftwidth=4: */

