Ticket #11118: 0001-Fix-video-encode-in-MPEG2-lossless-transcoding.patch

File 0001-Fix-video-encode-in-MPEG2-lossless-transcoding.patch, 4.1 KB (added by beirdo, 14 years ago)
  • mythtv/programs/mythtranscode/mpeg2fix.cpp

    From a5576e56f060f224b63f8bfe1bc12ff95ff210b7 Mon Sep 17 00:00:00 2001
    From: Gavin Hurlbut <ghurlbut@mythtv.org>
    Date: Sun, 23 Sep 2012 19:09:07 -0700
    Subject: [PATCH] Fix video encode in MPEG2 "lossless" transcoding
    
    Fixes #11118
    
    It seems that the new video encode API call pipelines the encoding, returning
    after each input frame, but not returning a packet the first time around in all
    cases.  This change makes it encode the packet, and then keep calling the API
    until a packet has actually been encoded (flushing the output).
    ---
     mythtv/programs/mythtranscode/mpeg2fix.cpp |   39 +++++++++++++++------------
     mythtv/programs/mythtranscode/mpeg2fix.h   |    2 +-
     2 files changed, 23 insertions(+), 18 deletions(-)
    
    diff --git a/mythtv/programs/mythtranscode/mpeg2fix.cpp b/mythtv/programs/mythtranscode/mpeg2fix.cpp
    index 0550e0b..23184f1 100644
    a b extern "C" {  
    10631063#include "helper.h"
    10641064}
    10651065
    1066 int MPEG2fixup::BuildFrame(AVPacket *pkt, QString fname)
     1066bool MPEG2fixup::BuildFrame(AVPacket *pkt, QString fname)
    10671067{
    10681068    const mpeg2_info_t *info;
    10691069    int outbuf_size;
    int MPEG2fixup::BuildFrame(AVPacket *pkt, QString fname)  
    10741074
    10751075    info = mpeg2_info(img_decoder);
    10761076    if (!info->display_fbuf)
    1077         return 1;
     1077        return true;
    10781078
    10791079    outbuf_size = info->sequence->width * info->sequence->height * 2;
    10801080
    int MPEG2fixup::BuildFrame(AVPacket *pkt, QString fname)  
    11161116    {
    11171117        free(picture);
    11181118        LOG(VB_GENERAL, LOG_ERR, "Couldn't find MPEG2 encoder");
    1119         return 1;
     1119        return true;
    11201120    }
    11211121
    11221122    c = avcodec_alloc_context3(NULL);
    11231123
    1124     //We disable all optimizations for the time being.  There shouldn't be too
    1125     //much encoding going on, and the optimizations have been shown to cause
    1126     //corruption in some cases
    1127     c->dsp_mask = 0xffff;
    1128 
    11291124    //NOTE: The following may seem wrong, but avcodec requires
    11301125    //sequence->progressive == frame->progressive
    11311126    //We fix the discrepancy by discarding avcodec's sequence header, and
    int MPEG2fixup::BuildFrame(AVPacket *pkt, QString fname)  
    11641159    {
    11651160        free(picture);
    11661161        LOG(VB_GENERAL, LOG_ERR, "could not open codec");
    1167         return 1;
     1162        return true;
    11681163    }
    11691164
    11701165    int got_packet = 0;
     1166    int ret;
     1167    bool initial = true;
    11711168
    1172     int ret = avcodec_encode_video2(c, pkt, picture, &got_packet);
    1173 
    1174     if (ret < 0 || !got_packet)
     1169    // Need to call this repeatedly as it seems to be pipelined.  The first
     1170    // call will return no packet, then the second one will flush it.  In case
     1171    // it becomes more pipelined, just loop until it creates a packet or errors
     1172    // out.
     1173    while (!got_packet)
    11751174    {
    1176         free(picture);
    1177         LOG(VB_GENERAL, LOG_ERR,
    1178             QString("avcodec_encode_video failed (%1)").arg(pkt->size));
    1179         return 1;
     1175        ret = avcodec_encode_video2(c, pkt, (initial ? picture : NULL),
     1176                                             &got_packet);
     1177
     1178        if (ret < 0)
     1179        {
     1180            free(picture);
     1181            LOG(VB_GENERAL, LOG_ERR,
     1182                QString("avcodec_encode_video2 failed (%1)").arg(ret));
     1183            return true;
     1184        }
    11801185    }
    11811186
    11821187    if (!fname.isEmpty())
    int MPEG2fixup::BuildFrame(AVPacket *pkt, QString fname)  
    11981203    av_freep(&c);
    11991204    av_freep(&picture);
    12001205
    1201     return 0;
     1206    return false;
    12021207}
    12031208
    12041209#define MAX_FRAMES 20000
  • mythtv/programs/mythtranscode/mpeg2fix.h

    diff --git a/mythtv/programs/mythtranscode/mpeg2fix.h b/mythtv/programs/mythtranscode/mpeg2fix.h
    index 96ecbbb..fe74ac0 100644
    a b class MPEG2fixup  
    171171    void WriteFrame(QString filename, AVPacket *pkt);
    172172    void WriteYUV(QString filename, const mpeg2_info_t *info);
    173173    void WriteData(QString filename, uint8_t *data, int size);
    174     int BuildFrame(AVPacket *pkt, QString fname);
     174    bool BuildFrame(AVPacket *pkt, QString fname);
    175175    MPEG2frame *GetPoolFrame(AVPacket *pkt);
    176176    MPEG2frame *GetPoolFrame(MPEG2frame *f);
    177177    int GetFrame(AVPacket *pkt);