[FFmpeg-devel] [PATCH] CrystalHD: Use mp4toannexb bitstream filter.
Philip Langdale
philipl at overt.org
Sat Jun 11 20:07:21 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 may
seem unfortunate as it requires an extra copy, but I suspect the
crystalhd library is doing it internally for non-Annex B streams
anyway.
This diff seems functional in that it prevents the parser errors
I was seeing when playing non-Annex B streams, but it apparently
doesn't fix the memory leak that wallak saw. In additional testing,
he showed that the filter was the source of the leak, so I must
be using it incorrectly, but I'm not sure what I should be doing
different.
---
libavcodec/crystalhd.c | 24 +++++++++++++++++++-----
1 files changed, 19 insertions(+), 5 deletions(-)
diff --git a/libavcodec/crystalhd.c b/libavcodec/crystalhd.c
index 3c80217..82fcbe8 100644
--- a/libavcodec/crystalhd.c
+++ b/libavcodec/crystalhd.c
@@ -124,6 +124,7 @@ typedef struct {
AVFrame pic;
HANDLE dev;
+ AVBitStreamFilterContext *bsfc;
AVCodecParserContext *parser;
uint8_t is_70012;
@@ -338,6 +339,9 @@ static av_cold int uninit(AVCodecContext *avctx)
DtsDeviceClose(device);
av_parser_close(priv->parser);
+ if (priv->bsfc) {
+ av_bitstream_filter_close(priv->bsfc);
+ }
av_free(priv->sps_pps_buf);
@@ -397,7 +401,6 @@ static av_cold int init(AVCodecContext *avctx)
{
uint8_t *dummy_p;
int dummy_int;
- AVBitStreamFilterContext *bsfc;
uint32_t orig_data_size = avctx->extradata_size;
uint8_t *orig_data = av_malloc(orig_data_size);
@@ -409,16 +412,15 @@ static av_cold int init(AVCodecContext *avctx)
memcpy(orig_data, avctx->extradata, orig_data_size);
- bsfc = av_bitstream_filter_init("h264_mp4toannexb");
- if (!bsfc) {
+ priv->bsfc = av_bitstream_filter_init("h264_mp4toannexb");
+ if (!priv->bsfc) {
av_log(avctx, AV_LOG_ERROR,
"Cannot open the h264_mp4toannexb BSF!\n");
av_free(orig_data);
return AVERROR_BSF_NOT_FOUND;
}
- av_bitstream_filter_filter(bsfc, avctx, NULL, &dummy_p,
+ av_bitstream_filter_filter(priv->bsfc, avctx, NULL, &dummy_p,
&dummy_int, NULL, 0, 0);
- av_bitstream_filter_close(bsfc);
priv->sps_pps_buf = avctx->extradata;
priv->sps_pps_size = avctx->extradata_size;
@@ -512,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");
@@ -831,6 +834,17 @@ static int decode(AVCodecContext *avctx, void *data, int *data_size, AVPacket *a
int32_t tx_free = (int32_t)DtsTxFreeSize(dev);
if (priv->parser) {
+ if (priv->bsfc) {
+ /*
+ * The filter API will always realloc and replace the input
+ * buffer, whether you want it to or not.
+ */
+ av_bitstream_filter_filter(priv->bsfc, avctx, NULL,
+ &avpkt->data, &avpkt->size,
+ avpkt->data, avpkt->size, 0);
+ len = avpkt->size;
+ }
+
uint8_t *pout;
int psize;
const uint8_t *in_data = avpkt->data;
--
1.7.4.1
More information about the ffmpeg-devel
mailing list