summaryrefslogtreecommitdiff
path: root/libavcodec/crystalhd.c
diff options
context:
space:
mode:
authorPhilip Langdale <philipl@overt.org>2016-10-08 20:34:00 -0700
committerPhilip Langdale <philipl@overt.org>2016-10-12 07:44:09 -0700
commit03d6d5f3760e2b06e3ef1f68de62c79c2e8fb173 (patch)
tree50bc37e226a216476e829894caa0cc38b144b07e /libavcodec/crystalhd.c
parentb5f45208fbe5373c7f9112a8169933b73a8478e1 (diff)
downloadffmpeg-03d6d5f3760e2b06e3ef1f68de62c79c2e8fb173.tar.gz
crystalhd: Use mpeg4_unpack_bframes to avoid buggy crystalhd handling
The hardware handling of packed bframes was always questionable but it used to ok with my workaround. Today, not so much. But today we have a bsf to unpack the bframes, so let's just use that and be done with it.
Diffstat (limited to 'libavcodec/crystalhd.c')
-rw-r--r--libavcodec/crystalhd.c127
1 files changed, 63 insertions, 64 deletions
diff --git a/libavcodec/crystalhd.c b/libavcodec/crystalhd.c
index 83be8e5d0c..912094088a 100644
--- a/libavcodec/crystalhd.c
+++ b/libavcodec/crystalhd.c
@@ -150,7 +150,6 @@ typedef struct {
/* Options */
uint32_t sWidth;
- uint8_t bframe_bug;
} CHDContext;
static const AVOption options[] = {
@@ -379,9 +378,59 @@ static av_cold int uninit(AVCodecContext *avctx)
}
+static av_cold int init_bsf(AVCodecContext *avctx, const char *bsf_name)
+{
+ CHDContext *priv = avctx->priv_data;
+ const AVBitStreamFilter *bsf;
+ int avret;
+ void *extradata = NULL;
+ size_t size = 0;
+
+ bsf = av_bsf_get_by_name(bsf_name);
+ if (!bsf) {
+ av_log(avctx, AV_LOG_ERROR,
+ "Cannot open the %s BSF!\n", bsf_name);
+ return AVERROR_BSF_NOT_FOUND;
+ }
+
+ avret = av_bsf_alloc(bsf, &priv->bsfc);
+ if (avret != 0) {
+ return avret;
+ }
+
+ avret = avcodec_parameters_from_context(priv->bsfc->par_in, avctx);
+ if (avret != 0) {
+ return avret;
+ }
+
+ avret = av_bsf_init(priv->bsfc);
+ if (avret != 0) {
+ return avret;
+ }
+
+ /* Back up the extradata so it can be restored at close time. */
+ priv->orig_extradata = avctx->extradata;
+ priv->orig_extradata_size = avctx->extradata_size;
+
+ size = priv->bsfc->par_out->extradata_size;
+ extradata = av_malloc(size + AV_INPUT_BUFFER_PADDING_SIZE);
+ if (!extradata) {
+ av_log(avctx, AV_LOG_ERROR,
+ "Failed to allocate copy of extradata\n");
+ return AVERROR(ENOMEM);
+ }
+ memcpy(extradata, priv->bsfc->par_out->extradata, size);
+
+ avctx->extradata = extradata;
+ avctx->extradata_size = size;
+
+ return 0;
+}
+
static av_cold int init(AVCodecContext *avctx)
{
CHDContext* priv;
+ int avret;
BC_STATUS ret;
BC_INFO_CRYSTAL version;
BC_INPUT_FORMAT format = {
@@ -417,46 +466,22 @@ static av_cold int init(AVCodecContext *avctx)
subtype = id2subtype(priv, avctx->codec->id);
switch (subtype) {
case BC_MSUBTYPE_AVC1:
- {
- const AVBitStreamFilter *bsf;
- int avret;
-
- bsf = av_bsf_get_by_name("h264_mp4toannexb");
- if (!bsf) {
- av_log(avctx, AV_LOG_ERROR,
- "Cannot open the h264_mp4toannexb BSF!\n");
- return AVERROR_BSF_NOT_FOUND;
- }
- avret = av_bsf_alloc(bsf, &priv->bsfc);
- if (avret != 0) {
- return AVERROR(ENOMEM);
- }
- avret = avcodec_parameters_from_context(priv->bsfc->par_in, avctx);
- if (avret != 0) {
- return AVERROR(ENOMEM);
- }
- avret = av_bsf_init(priv->bsfc);
- if (avret != 0) {
- return AVERROR(ENOMEM);
- }
-
- format.metaDataSz = priv->bsfc->par_out->extradata_size;
- format.pMetaData = av_malloc(format.metaDataSz + AV_INPUT_BUFFER_PADDING_SIZE);
- if (!format.pMetaData) {
- av_log(avctx, AV_LOG_ERROR,
- "Failed to allocate copy of extradata\n");
- return AVERROR(ENOMEM);
- }
- memcpy(format.pMetaData, priv->bsfc->par_out->extradata, format.metaDataSz);
-
- /* Back up the extradata so it can be restored at close time. */
- priv->orig_extradata = avctx->extradata;
- priv->orig_extradata_size = avctx->extradata_size;
- avctx->extradata = format.pMetaData;
- avctx->extradata_size = format.metaDataSz;
+ avret = init_bsf(avctx, "h264_mp4toannexb");
+ if (avret != 0) {
+ return avret;
}
subtype = BC_MSUBTYPE_H264;
format.startCodeSz = 4;
+ 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;
@@ -466,7 +491,6 @@ 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;
@@ -839,15 +863,6 @@ 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) {
- 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) {
@@ -908,22 +923,6 @@ static int decode(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *a
av_log(avctx, AV_LOG_VERBOSE, "CrystalHD: decode_frame\n");
- if (avpkt->size == 7 && !priv->bframe_bug) {
- /*
- * The use of a drop frame triggers the bug
- */
- av_log(avctx, AV_LOG_INFO,
- "CrystalHD: Enabling work-around for packed b-frame bug\n");
- priv->bframe_bug = 1;
- } else if (avpkt->size == 8 && priv->bframe_bug) {
- /*
- * Delay frames don't trigger the bug
- */
- av_log(avctx, AV_LOG_INFO,
- "CrystalHD: Disabling work-around for packed b-frame bug\n");
- priv->bframe_bug = 0;
- }
-
if (len) {
int32_t tx_free = (int32_t)DtsTxFreeSize(dev);