summaryrefslogtreecommitdiff
path: root/libavcodec/crystalhd.c
diff options
context:
space:
mode:
authorPhilip Langdale <philipl@overt.org>2016-10-15 15:50:29 -0700
committerPhilip Langdale <philipl@overt.org>2016-11-02 13:47:57 -0700
commit6cc390dd5a53623de14010c0ae9067e345e36565 (patch)
treeda2e240f6460864bbda31c35c2ac600b5b933c77 /libavcodec/crystalhd.c
parentb5d714f493946f02b957f57e491321abc816e753 (diff)
downloadffmpeg-6cc390dd5a53623de14010c0ae9067e345e36565.tar.gz
crystalhd: Revert back to letting hardware handle packed b-frames
I'm not sure why, but the mpeg4_unpack_bframes bsf is not interacting well with seeking. Looking at the code, it should be ok, with possibly one warning shown, but I see it getting stuck for an extended period of time after a seek where a packed frame is cached to be shown later. So, I gave up on that and went back to making the old hardware based path work. Turns out that it wasn't broken except that some samples have a 6 byte drop packet which I wasn't accounting for. Now it works again and seeks are good.
Diffstat (limited to 'libavcodec/crystalhd.c')
-rw-r--r--libavcodec/crystalhd.c37
1 files changed, 29 insertions, 8 deletions
diff --git a/libavcodec/crystalhd.c b/libavcodec/crystalhd.c
index dca58f2c8b..c1ca066d2f 100644
--- a/libavcodec/crystalhd.c
+++ b/libavcodec/crystalhd.c
@@ -140,6 +140,7 @@ typedef struct {
/* Options */
uint32_t sWidth;
+ uint8_t bframe_bug;
} CHDContext;
static const AVOption options[] = {
@@ -460,14 +461,6 @@ static av_cold int init(AVCodecContext *avctx)
format.pMetaData = avctx->extradata;
format.metaDataSz = avctx->extradata_size;
break;
- case BC_MSUBTYPE_DIVX:
- avret = init_bsf(avctx, "mpeg4_unpack_bframes");
- if (avret != 0) {
- return avret;
- }
- format.pMetaData = avctx->extradata;
- format.metaDataSz = avctx->extradata_size;
- break;
case BC_MSUBTYPE_H264:
format.startCodeSz = 4;
// Fall-through
@@ -476,6 +469,7 @@ static av_cold int init(AVCodecContext *avctx)
case BC_MSUBTYPE_WMV3:
case BC_MSUBTYPE_WMVA:
case BC_MSUBTYPE_MPEG2VIDEO:
+ case BC_MSUBTYPE_DIVX:
case BC_MSUBTYPE_DIVX311:
format.pMetaData = avctx->extradata;
format.metaDataSz = avctx->extradata_size;
@@ -829,6 +823,17 @@ static inline CopyRet receive_frame(AVCodecContext *avctx,
priv->last_picture = output.PicInfo.picture_number - 1;
}
+ if (avctx->codec->id == AV_CODEC_ID_MPEG4 &&
+ output.PicInfo.timeStamp == 0 && priv->bframe_bug) {
+ if (!priv->bframe_bug) {
+ av_log(avctx, AV_LOG_VERBOSE,
+ "CrystalHD: Not returning packed frame twice.\n");
+ }
+ priv->last_picture++;
+ DtsReleaseOutputBuffs(dev, NULL, FALSE);
+ return RET_COPY_AGAIN;
+ }
+
print_frame_info(priv, &output);
if (priv->last_picture + 1 < output.PicInfo.picture_number) {
@@ -879,6 +884,22 @@ static int crystalhd_decode_packet(AVCodecContext *avctx, const AVPacket *avpkt)
if (avpkt && avpkt->size) {
int32_t tx_free = (int32_t)DtsTxFreeSize(dev);
+ if (!priv->bframe_bug && (avpkt->size == 6 || avpkt->size == 7)) {
+ /*
+ * Drop frames trigger the bug
+ */
+ av_log(avctx, AV_LOG_WARNING,
+ "CrystalHD: Enabling work-around for packed b-frame bug\n");
+ priv->bframe_bug = 1;
+ } else if (priv->bframe_bug && avpkt->size == 8) {
+ /*
+ * Delay frames don't trigger the bug
+ */
+ av_log(avctx, AV_LOG_WARNING,
+ "CrystalHD: Disabling work-around for packed b-frame bug\n");
+ priv->bframe_bug = 0;
+ }
+
if (priv->bsfc) {
AVPacket filter_packet = { 0 };