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) |
3581 | 3581 | else |
3582 | 3582 | { |
3583 | 3583 | 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. |
3585 | 3602 | } |
3586 | 3603 | avcodeclock->unlock(); |
3587 | 3604 | |
3588 | 3605 | if (ret < 0) |
3589 | 3606 | { |
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)); |
3591 | 3612 | return false; |
3592 | 3613 | } |
3593 | 3614 | |
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) |
1873 | 1873 | MythAVFrame picture; |
1874 | 1874 | AVPacket pkt; |
1875 | 1875 | uint8_t *buff = NULL; |
1876 | | int gotPicture = 0, len; |
| 1876 | bool gotPicture = false; |
| 1877 | int len; |
1877 | 1878 | m_image = QImage(); |
1878 | 1879 | |
1879 | 1880 | // Find the mpeg2 video decoder. |
… |
… |
void MHIBitmap::CreateFromMPEG(const unsigned char *data, int length) |
1895 | 1896 | memcpy(pkt.data, data, length); |
1896 | 1897 | buff = pkt.data; |
1897 | 1898 | |
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++) |
1899 | 1902 | { |
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)); |
1913 | 1919 | goto Close; |
| 1920 | } |
| 1921 | else |
| 1922 | { |
| 1923 | pkt.data = NULL; |
| 1924 | pkt.size = 0; |
| 1925 | } |
1914 | 1926 | } |
1915 | 1927 | |
1916 | 1928 | if (gotPicture) |
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, |
923 | 923 | { |
924 | 924 | QMutexLocker locker(avcodeclock); |
925 | 925 | // 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); |
929 | 940 | 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. |
930 | 946 | if (ret < 0) |
931 | 947 | { |
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)); |
935 | 953 | } |
936 | | else if (!gotpicture) |
| 954 | if (!gotpicture) |
937 | 955 | { |
938 | 956 | return false; |
939 | 957 | } |