Commit 7447ec91 authored by Philip Langdale's avatar Philip Langdale

crystalhd: Use up-to-date bsf API

Although the old API is supposed to be functional, the crystalhd
decoder is currently not working for non-annex.b h.264 content.

So, let's update to the modern API and make it work again.
Signed-off-by: 's avatarPhilip Langdale <philipl@overt.org>
parent 0b420886
...@@ -131,7 +131,7 @@ typedef struct { ...@@ -131,7 +131,7 @@ typedef struct {
uint8_t *orig_extradata; uint8_t *orig_extradata;
uint32_t orig_extradata_size; uint32_t orig_extradata_size;
AVBitStreamFilterContext *bsfc; AVBSFContext *bsfc;
AVCodecParserContext *parser; AVCodecParserContext *parser;
uint8_t is_70012; uint8_t is_70012;
...@@ -359,7 +359,7 @@ static av_cold int uninit(AVCodecContext *avctx) ...@@ -359,7 +359,7 @@ static av_cold int uninit(AVCodecContext *avctx)
av_parser_close(priv->parser); av_parser_close(priv->parser);
if (priv->bsfc) { if (priv->bsfc) {
av_bitstream_filter_close(priv->bsfc); av_bsf_free(&priv->bsfc);
} }
av_freep(&priv->sps_pps_buf); av_freep(&priv->sps_pps_buf);
...@@ -418,30 +418,46 @@ static av_cold int init(AVCodecContext *avctx) ...@@ -418,30 +418,46 @@ static av_cold int init(AVCodecContext *avctx)
switch (subtype) { switch (subtype) {
case BC_MSUBTYPE_AVC1: case BC_MSUBTYPE_AVC1:
{ {
uint8_t *dummy_p; const AVBitStreamFilter *bsf;
int dummy_int; int avret;
/* Back up the extradata so it can be restored at close time. */ bsf = av_bsf_get_by_name("h264_mp4toannexb");
priv->orig_extradata = av_malloc(avctx->extradata_size + AV_INPUT_BUFFER_PADDING_SIZE); if (!bsf) {
if (!priv->orig_extradata) {
av_log(avctx, AV_LOG_ERROR, av_log(avctx, AV_LOG_ERROR,
"Failed to allocate copy of extradata\n"); "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); return AVERROR(ENOMEM);
} }
priv->orig_extradata_size = avctx->extradata_size;
memcpy(priv->orig_extradata, avctx->extradata, avctx->extradata_size);
priv->bsfc = av_bitstream_filter_init("h264_mp4toannexb"); format.metaDataSz = priv->bsfc->par_out->extradata_size;
if (!priv->bsfc) { format.pMetaData = av_malloc(format.metaDataSz + AV_INPUT_BUFFER_PADDING_SIZE);
if (!format.pMetaData) {
av_log(avctx, AV_LOG_ERROR, av_log(avctx, AV_LOG_ERROR,
"Cannot open the h264_mp4toannexb BSF!\n"); "Failed to allocate copy of extradata\n");
return AVERROR_BSF_NOT_FOUND; return AVERROR(ENOMEM);
} }
av_bitstream_filter_filter(priv->bsfc, avctx, NULL, &dummy_p, memcpy(format.pMetaData, priv->bsfc->par_out->extradata, format.metaDataSz);
&dummy_int, NULL, 0, 0);
/* 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;
} }
subtype = BC_MSUBTYPE_H264; subtype = BC_MSUBTYPE_H264;
// Fall-through format.startCodeSz = 4;
break;
case BC_MSUBTYPE_H264: case BC_MSUBTYPE_H264:
format.startCodeSz = 4; format.startCodeSz = 4;
// Fall-through // Fall-through
...@@ -901,14 +917,41 @@ static int decode(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *a ...@@ -901,14 +917,41 @@ static int decode(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *a
if (len) { if (len) {
int32_t tx_free = (int32_t)DtsTxFreeSize(dev); int32_t tx_free = (int32_t)DtsTxFreeSize(dev);
if (priv->parser) { if (priv->bsfc) {
int ret = 0; int ret = 0;
AVPacket filter_packet = { 0 };
AVPacket filtered_packet = { 0 };
ret = av_packet_ref(&filter_packet, avpkt);
if (ret < 0) {
av_log(avctx, AV_LOG_ERROR, "CrystalHD: mpv4toannexb filter "
"failed to ref input packet\n");
return ret;
}
ret = av_bsf_send_packet(priv->bsfc, &filter_packet);
if (ret < 0) {
av_log(avctx, AV_LOG_ERROR, "CrystalHD: mpv4toannexb filter "
"failed to send input packet\n");
return ret;
}
if (priv->bsfc) { ret = av_bsf_receive_packet(priv->bsfc, &filtered_packet);
ret = av_bitstream_filter_filter(priv->bsfc, avctx, NULL, if (ret < 0) {
&in_data, &len, av_log(avctx, AV_LOG_ERROR, "CrystalHD: mpv4toannexb filter "
avpkt->data, len, 0); "failed to receive output packet\n");
return ret;
} }
in_data = filtered_packet.data;
len = filtered_packet.size;
av_packet_unref(&filter_packet);
}
if (priv->parser) {
int ret = 0;
free_data = ret > 0; free_data = ret > 0;
if (ret >= 0) { if (ret >= 0) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment