Browse code

CrystalHD: Bring in h.264 parser to establish picture type.

As the hardware is unreliable, we will have to use the h.264 parser
to identify whether an input picture is a field or a frame. This
change loads the parser and extracts the picture type.

Signed-off-by: Philip Langdale <philipl@overt.org>

Philip Langdale authored on 2011/03/26 14:46:22
Showing 2 changed files
... ...
@@ -1279,7 +1279,7 @@ h263_vaapi_hwaccel_select="vaapi h263_decoder"
1279 1279
 h263i_decoder_select="h263_decoder"
1280 1280
 h263p_encoder_select="h263_encoder"
1281 1281
 h264_decoder_select="golomb h264dsp h264pred"
1282
-h264_crystalhd_decoder_select="crystalhd h264_mp4toannexb_bsf"
1282
+h264_crystalhd_decoder_select="crystalhd h264_mp4toannexb_bsf h264_parser"
1283 1283
 h264_dxva2_hwaccel_deps="dxva2api_h"
1284 1284
 h264_dxva2_hwaccel_select="dxva2 h264_decoder"
1285 1285
 h264_vaapi_hwaccel_select="vaapi"
... ...
@@ -84,6 +84,7 @@
84 84
 #include <libcrystalhd/libcrystalhd_if.h>
85 85
 
86 86
 #include "avcodec.h"
87
+#include "h264.h"
87 88
 #include "libavutil/imgutils.h"
88 89
 #include "libavutil/intreadwrite.h"
89 90
 
... ...
@@ -120,6 +121,8 @@ typedef struct {
120 120
     AVFrame pic;
121 121
     HANDLE dev;
122 122
 
123
+    AVCodecParserContext *parser;
124
+
123 125
     uint8_t is_70012;
124 126
     uint8_t *sps_pps_buf;
125 127
     uint32_t sps_pps_size;
... ...
@@ -316,6 +319,8 @@ static av_cold int uninit(AVCodecContext *avctx)
316 316
     DtsCloseDecoder(device);
317 317
     DtsDeviceClose(device);
318 318
 
319
+    av_parser_close(priv->parser);
320
+
319 321
     av_free(priv->sps_pps_buf);
320 322
 
321 323
     if (priv->pic.data[0])
... ...
@@ -478,6 +483,13 @@ static av_cold int init(AVCodecContext *avctx)
478 478
         goto fail;
479 479
     }
480 480
 
481
+    if (avctx->codec->id == CODEC_ID_H264) {
482
+        priv->parser = av_parser_init(avctx->codec->id);
483
+        if (!priv->parser)
484
+            av_log(avctx, AV_LOG_WARNING,
485
+                   "Cannot open the h.264 parser! Interlaced h.264 content "
486
+                   "will not be detected reliably.\n");
487
+    }
481 488
     av_log(avctx, AV_LOG_VERBOSE, "CrystalHD: Init complete.\n");
482 489
 
483 490
     return 0;
... ...
@@ -737,11 +749,28 @@ static int decode(AVCodecContext *avctx, void *data, int *data_size, AVPacket *a
737 737
     CHDContext *priv   = avctx->priv_data;
738 738
     HANDLE dev         = priv->dev;
739 739
     int len            = avpkt->size;
740
+    uint8_t pic_type   = 0;
740 741
 
741 742
     av_log(avctx, AV_LOG_VERBOSE, "CrystalHD: decode_frame\n");
742 743
 
743 744
     if (len) {
744 745
         int32_t tx_free = (int32_t)DtsTxFreeSize(dev);
746
+
747
+        if (priv->parser) {
748
+            uint8_t *pout;
749
+            int psize = len;
750
+            H264Context *h = priv->parser->priv_data;
751
+
752
+            while (psize)
753
+                ret = av_parser_parse2(priv->parser, avctx, &pout, &psize,
754
+                                       avpkt->data, len, avctx->pkt->pts,
755
+                                       avctx->pkt->dts, len - psize);
756
+            av_log(avctx, AV_LOG_VERBOSE,
757
+                   "CrystalHD: parser picture type %d\n",
758
+                   h->s.picture_structure);
759
+            pic_type = h->s.picture_structure;
760
+        }
761
+
745 762
         if (len < tx_free - 1024) {
746 763
             /*
747 764
              * Despite being notionally opaque, either libcrystalhd or