[FFmpeg-devel] [PATCH 2/2] CrystalHD: Use mp4toannexb bitstream filter.

Philip Langdale philipl at overt.org
Mon Jun 13 05:39:28 CEST 2011


The H.264 parser that we use to detect interlacing can only handle
an Annex B stream, so we need to actually use the filter. This is
unfortunate as the crystalhd library is already doing this conversion
internally. A future change will reorganise the decode path more
completely so that we can feed the converted stream into libcrystalhd
and avoid the second conversion.

Signed-off-by: Philip Langdale <philipl at overt.org>
---
 libavcodec/crystalhd.c |   48 +++++++++++++++++++++++++++++++++++++-----------
 1 files changed, 37 insertions(+), 11 deletions(-)

diff --git a/libavcodec/crystalhd.c b/libavcodec/crystalhd.c
index 851abd7..ce1cd55 100644
--- a/libavcodec/crystalhd.c
+++ b/libavcodec/crystalhd.c
@@ -514,6 +514,7 @@ static av_cold int init(AVCodecContext *avctx)
             av_log(avctx, AV_LOG_WARNING,
                    "Cannot open the h.264 parser! Interlaced h.264 content "
                    "will not be detected reliably.\n");
+        priv->parser->flags = PARSER_FLAG_COMPLETE_FRAMES;
     }
     av_log(avctx, AV_LOG_VERBOSE, "CrystalHD: Init complete.\n");
 
@@ -833,24 +834,49 @@ static int decode(AVCodecContext *avctx, void *data, int *data_size, AVPacket *a
         int32_t tx_free = (int32_t)DtsTxFreeSize(dev);
 
         if (priv->parser) {
-            uint8_t *pout;
-            int psize;
-            const uint8_t *in_data = avpkt->data;
+            uint8_t *in_data = avpkt->data;
             int in_len = len;
-            H264Context *h = priv->parser->priv_data;
+            int ret = 0;
 
-            while (in_len) {
+            if (priv->bsfc) {
+                ret = av_bitstream_filter_filter(priv->bsfc, avctx, NULL,
+                                                 &in_data, &in_len,
+                                                 avpkt->data, len, 0);
+            }
+
+            if (ret >= 0) {
+                uint8_t *pout;
+                int psize;
                 int index;
+                H264Context *h = priv->parser->priv_data;
+
                 index = av_parser_parse2(priv->parser, avctx, &pout, &psize,
                                          in_data, in_len, avctx->pkt->pts,
                                          avctx->pkt->dts, 0);
-                in_data += index;
-                in_len -= index;
+                if (index < 0) {
+                    av_log(avctx, AV_LOG_WARNING,
+                           "CrystalHD: Failed to parse h.264 packet to "
+                           "detect interlacing.\n");
+                } else if (index != in_len) {
+                    av_log(avctx, AV_LOG_WARNING,
+                           "CrystalHD: Failed to parse h.264 packet "
+                           "completely. Interlaced frames may be "
+                           "incorrectly detected\n.");
+                } else {
+                    av_log(avctx, AV_LOG_VERBOSE,
+                           "CrystalHD: parser picture type %d\n",
+                           h->s.picture_structure);
+                    pic_type = h->s.picture_structure;
+                }
+            } else {
+                av_log(avctx, AV_LOG_WARNING,
+                       "CrystalHD: mp4toannexb filter failed to filter "
+                       "packet. Interlaced frames may be incorrectly "
+                       "detected.\n");
+            }
+            if (ret > 0) {
+                av_freep(&in_data);
             }
-            av_log(avctx, AV_LOG_VERBOSE,
-                   "CrystalHD: parser picture type %d\n",
-                   h->s.picture_structure);
-            pic_type = h->s.picture_structure;
         }
 
         if (len < tx_free - 1024) {
-- 
1.7.4.1



More information about the ffmpeg-devel mailing list