Ticket #13186: 004_avcodec_decode_video2.patch

File 004_avcodec_decode_video2.patch, 5.9 KB (added by Peter Bennett, 3 years ago)

Patch 004 - avcodec_decode_video2

  • mythtv/libs/libmythtv/avformatdecoder.cpp

    diff --git a/mythtv/libs/libmythtv/avformatdecoder.cpp b/mythtv/libs/libmythtv/avformatdecoder.cpp
    index f7fd572..aa5056c 100644
    a b bool AvFormatDecoder::ProcessVideoPacket(AVStream *curstream, AVPacket *pkt) 
    35813581    else
    35823582    {
    35833583        context->reordered_opaque = pkt->pts;
    3584         ret = avcodec_decode_video2(context, mpa_pic, &gotpicture, pkt);
     3584        //  SUGGESTION
     3585        //  Now that avcodec_decode_video2 is deprecated and replaced
     3586        //  by 2 calls (receive frame and send packet), this could be optimized
     3587        //  into separate routines or separate threads.
     3588        //  Also now that it always consumes a whole buffer some code
     3589        //  in the caller may be able to be optimized.
     3590        ret = avcodec_receive_frame(context, mpa_pic);
     3591        if (ret == 0)
     3592            gotpicture = 1;
     3593        if (ret == AVERROR(EAGAIN))
     3594            ret = 0;
     3595        if (ret == 0)
     3596            ret = avcodec_send_packet(context, pkt);
     3597        // The code assumes that there is always space to add a new
     3598        // packet. This seems risky but has always worked.
     3599        // It should actually check if (ret == AVERROR(EAGAIN)) and then keep
     3600        // the packet around and try it again after processing the frame
     3601        // received here.
    35853602    }
    35863603    avcodeclock->unlock();
    35873604
    35883605    if (ret < 0)
    35893606    {
    3590         LOG(VB_GENERAL, LOG_ERR, LOC + "Unknown decoding error");
     3607        char error[AV_ERROR_MAX_STRING_SIZE];
     3608        LOG(VB_GENERAL, LOG_ERR, LOC +
     3609            QString("video decode error: %1 (%2)")
     3610            .arg(av_make_error_string(error, sizeof(error), ret))
     3611            .arg(gotpicture));
    35913612        return false;
    35923613    }
    35933614
  • mythtv/libs/libmythtv/mhi.cpp

    diff --git a/mythtv/libs/libmythtv/mhi.cpp b/mythtv/libs/libmythtv/mhi.cpp
    index 3d9a7e4..9423dce 100644
    a b void MHIBitmap::CreateFromMPEG(const unsigned char *data, int length) 
    18731873    MythAVFrame picture;
    18741874    AVPacket pkt;
    18751875    uint8_t *buff = NULL;
    1876     int gotPicture = 0, len;
     1876    bool gotPicture = false;
     1877    int len;
    18771878    m_image = QImage();
    18781879
    18791880    // Find the mpeg2 video decoder.
    void MHIBitmap::CreateFromMPEG(const unsigned char *data, int length) 
    18951896    memcpy(pkt.data, data, length);
    18961897    buff = pkt.data;
    18971898
    1898     while (pkt.size > 0 && ! gotPicture)
     1899    // Get a picture from the packet. Allow 9 loops for
     1900    // packet to be decoded. It should take only 2-3 loops
     1901    for (int limit=0; limit<10 && !gotPicture; limit++)
    18991902    {
    1900         len = avcodec_decode_video2(c, picture, &gotPicture, &pkt);
    1901         if (len < 0) // Error
    1902             goto Close;
    1903         pkt.data += len;
    1904         pkt.size -= len;
    1905     }
    1906 
    1907     if (!gotPicture)
    1908     {
    1909         pkt.data = NULL;
    1910         pkt.size = 0;
    1911         // Process any buffered data
    1912         if (avcodec_decode_video2(c, picture, &gotPicture, &pkt) < 0)
     1903        len = avcodec_receive_frame(c, picture);
     1904        if (len == 0)
     1905            gotPicture = true;
     1906        if (len == AVERROR(EAGAIN))
     1907            len = 0;
     1908        if (len == 0)
     1909            len = avcodec_send_packet(c, &pkt);
     1910        if (len == AVERROR(EAGAIN) || len == AVERROR_EOF)
     1911            len = 0;
     1912        else if (len < 0) // Error
     1913        {
     1914            char error[AV_ERROR_MAX_STRING_SIZE];
     1915            LOG(VB_GENERAL, LOG_ERR,
     1916                QString("[mhi] video decode error: %1 (%2)")
     1917                .arg(av_make_error_string(error, sizeof(error), len))
     1918                .arg(gotPicture));
    19131919            goto Close;
     1920        }
     1921        else
     1922        {
     1923            pkt.data = NULL;
     1924            pkt.size = 0;
     1925        }
    19141926    }
    19151927
    19161928    if (gotPicture)
  • mythtv/libs/libmythtv/nuppeldecoder.cpp

    diff --git a/mythtv/libs/libmythtv/nuppeldecoder.cpp b/mythtv/libs/libmythtv/nuppeldecoder.cpp
    index 9079c17..f1a4d08 100644
    a b bool NuppelDecoder::DecodeFrame(struct rtframeheader *frameheader, 
    923923        {
    924924            QMutexLocker locker(avcodeclock);
    925925            // if directrendering, writes into buf
    926             int gotpicture = 0;
    927             int ret = avcodec_decode_video2(mpa_vidctx, mpa_pic, &gotpicture,
    928                                             &pkt);
     926            bool gotpicture = false;
     927            //  SUGGESTION
     928            //  Now that avcodec_decode_video2 is deprecated and replaced
     929            //  by 2 calls (receive frame and send packet), this could be optimized
     930            //  into separate routines or separate threads.
     931            //  Also now that it always consumes a whole buffer some code
     932            //  in the caller may be able to be optimized.
     933            int ret = avcodec_receive_frame(mpa_vidctx, mpa_pic);
     934            if (ret == 0)
     935                gotpicture = true;
     936            if (ret == AVERROR(EAGAIN))
     937                ret = 0;
     938            if (ret == 0)
     939                ret = avcodec_send_packet(mpa_vidctx, &pkt);
    929940            directframe = NULL;
     941            // The code assumes that there is always space to add a new
     942            // packet. This seems risky but has always worked.
     943            // It should actually check if (ret == AVERROR(EAGAIN)) and then keep
     944            // the packet around and try it again after processing the frame
     945            // received here.
    930946            if (ret < 0)
    931947            {
    932                 LOG(VB_PLAYBACK, LOG_ERR, LOC +
    933                     QString("avcodec_decode_video returned: %1").arg(ret));
    934                 return false;
     948                char error[AV_ERROR_MAX_STRING_SIZE];
     949                LOG(VB_GENERAL, LOG_ERR, LOC +
     950                    QString("video decode error: %1 (%2)")
     951                    .arg(av_make_error_string(error, sizeof(error), ret))
     952                    .arg(gotpicture));
    935953            }
    936             else if (!gotpicture)
     954            if (!gotpicture)
    937955            {
    938956                return false;
    939957            }