You've already forked FFmpeg
mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2025-08-15 14:13:16 +02:00
Merge commit '8e2ea691351c5079cdab245ff7bfa5c0f3e3bfe4'
* commit '8e2ea691351c5079cdab245ff7bfa5c0f3e3bfe4': lavf: use the new bitstream filter for extracting extradata Merged-by: James Almer <jamrial@gmail.com>
This commit is contained in:
@@ -178,6 +178,15 @@ struct AVStreamInternal {
|
|||||||
|
|
||||||
enum AVCodecID orig_codec_id;
|
enum AVCodecID orig_codec_id;
|
||||||
|
|
||||||
|
/* the context for extracting extradata in find_stream_info()
|
||||||
|
* inited=1/bsf=NULL signals that extracting is not possible (codec not
|
||||||
|
* supported) */
|
||||||
|
struct {
|
||||||
|
AVBSFContext *bsf;
|
||||||
|
AVPacket *pkt;
|
||||||
|
int inited;
|
||||||
|
} extract_extradata;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether the internal avctx needs to be updated from codecpar (after a late change to codecpar)
|
* Whether the internal avctx needs to be updated from codecpar (after a late change to codecpar)
|
||||||
*/
|
*/
|
||||||
|
@@ -3370,6 +3370,104 @@ void ff_rfps_calculate(AVFormatContext *ic)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int extract_extradata_init(AVStream *st)
|
||||||
|
{
|
||||||
|
AVStreamInternal *i = st->internal;
|
||||||
|
const AVBitStreamFilter *f;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
f = av_bsf_get_by_name("extract_extradata");
|
||||||
|
if (!f)
|
||||||
|
goto finish;
|
||||||
|
|
||||||
|
i->extract_extradata.pkt = av_packet_alloc();
|
||||||
|
if (!i->extract_extradata.pkt)
|
||||||
|
return AVERROR(ENOMEM);
|
||||||
|
|
||||||
|
ret = av_bsf_alloc(f, &i->extract_extradata.bsf);
|
||||||
|
if (ret < 0)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
ret = avcodec_parameters_copy(i->extract_extradata.bsf->par_in,
|
||||||
|
st->codecpar);
|
||||||
|
if (ret < 0)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
i->extract_extradata.bsf->time_base_in = st->time_base;
|
||||||
|
|
||||||
|
/* if init fails here, we assume extracting extradata is just not
|
||||||
|
* supported for this codec, so we return success */
|
||||||
|
ret = av_bsf_init(i->extract_extradata.bsf);
|
||||||
|
if (ret < 0) {
|
||||||
|
av_bsf_free(&i->extract_extradata.bsf);
|
||||||
|
ret = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
finish:
|
||||||
|
i->extract_extradata.inited = 1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
fail:
|
||||||
|
av_bsf_free(&i->extract_extradata.bsf);
|
||||||
|
av_packet_free(&i->extract_extradata.pkt);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int extract_extradata(AVStream *st, AVPacket *pkt)
|
||||||
|
{
|
||||||
|
AVStreamInternal *i = st->internal;
|
||||||
|
AVPacket *pkt_ref;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (!i->extract_extradata.inited) {
|
||||||
|
ret = extract_extradata_init(st);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i->extract_extradata.inited && !i->extract_extradata.bsf)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
pkt_ref = i->extract_extradata.pkt;
|
||||||
|
ret = av_packet_ref(pkt_ref, pkt);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
ret = av_bsf_send_packet(i->extract_extradata.bsf, pkt_ref);
|
||||||
|
if (ret < 0) {
|
||||||
|
av_packet_unref(pkt_ref);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (ret >= 0 && !i->avctx->extradata) {
|
||||||
|
int extradata_size;
|
||||||
|
uint8_t *extradata;
|
||||||
|
|
||||||
|
ret = av_bsf_receive_packet(i->extract_extradata.bsf, pkt_ref);
|
||||||
|
if (ret < 0) {
|
||||||
|
if (ret != AVERROR(EAGAIN) && ret != AVERROR_EOF)
|
||||||
|
return ret;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
extradata = av_packet_get_side_data(pkt_ref, AV_PKT_DATA_NEW_EXTRADATA,
|
||||||
|
&extradata_size);
|
||||||
|
|
||||||
|
if (extradata) {
|
||||||
|
i->avctx->extradata = av_mallocz(extradata_size + AV_INPUT_BUFFER_PADDING_SIZE);
|
||||||
|
if (!i->avctx->extradata) {
|
||||||
|
av_packet_unref(pkt_ref);
|
||||||
|
return AVERROR(ENOMEM);
|
||||||
|
}
|
||||||
|
memcpy(i->avctx->extradata, extradata, extradata_size);
|
||||||
|
i->avctx->extradata_size = extradata_size;
|
||||||
|
}
|
||||||
|
av_packet_unref(pkt_ref);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options)
|
int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options)
|
||||||
{
|
{
|
||||||
int i, count = 0, ret = 0, j;
|
int i, count = 0, ret = 0, j;
|
||||||
@@ -3529,8 +3627,10 @@ FF_ENABLE_DEPRECATION_WARNINGS
|
|||||||
if (count < fps_analyze_framecount)
|
if (count < fps_analyze_framecount)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (st->parser && st->parser->parser->split &&
|
if (!st->codecpar->extradata &&
|
||||||
!st->internal->avctx->extradata)
|
!st->internal->avctx->extradata &&
|
||||||
|
(!st->internal->extract_extradata.inited ||
|
||||||
|
st->internal->extract_extradata.bsf))
|
||||||
break;
|
break;
|
||||||
if (st->first_dts == AV_NOPTS_VALUE &&
|
if (st->first_dts == AV_NOPTS_VALUE &&
|
||||||
!(ic->iformat->flags & AVFMT_NOTIMESTAMPS) &&
|
!(ic->iformat->flags & AVFMT_NOTIMESTAMPS) &&
|
||||||
@@ -3680,17 +3780,10 @@ FF_ENABLE_DEPRECATION_WARNINGS
|
|||||||
if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
|
if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
|
||||||
ff_rfps_add_frame(ic, st, pkt->dts);
|
ff_rfps_add_frame(ic, st, pkt->dts);
|
||||||
#endif
|
#endif
|
||||||
if (st->parser && st->parser->parser->split && !avctx->extradata) {
|
if (!st->internal->avctx->extradata) {
|
||||||
int i = st->parser->parser->split(avctx, pkt->data, pkt->size);
|
ret = extract_extradata(st, pkt);
|
||||||
if (i > 0 && i < FF_MAX_EXTRADATA_SIZE) {
|
if (ret < 0)
|
||||||
avctx->extradata_size = i;
|
goto find_stream_info_err;
|
||||||
avctx->extradata = av_mallocz(avctx->extradata_size +
|
|
||||||
AV_INPUT_BUFFER_PADDING_SIZE);
|
|
||||||
if (!avctx->extradata)
|
|
||||||
return AVERROR(ENOMEM);
|
|
||||||
memcpy(avctx->extradata, pkt->data,
|
|
||||||
avctx->extradata_size);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If still no information, we try to open the codec and to
|
/* If still no information, we try to open the codec and to
|
||||||
@@ -3950,6 +4043,8 @@ find_stream_info_err:
|
|||||||
if (st->info)
|
if (st->info)
|
||||||
av_freep(&st->info->duration_error);
|
av_freep(&st->info->duration_error);
|
||||||
av_freep(&ic->streams[i]->info);
|
av_freep(&ic->streams[i]->info);
|
||||||
|
av_bsf_free(&ic->streams[i]->internal->extract_extradata.bsf);
|
||||||
|
av_packet_free(&ic->streams[i]->internal->extract_extradata.pkt);
|
||||||
}
|
}
|
||||||
if (ic->pb)
|
if (ic->pb)
|
||||||
av_log(ic, AV_LOG_DEBUG, "After avformat_find_stream_info() pos: %"PRId64" bytes read:%"PRId64" seeks:%d frames:%d\n",
|
av_log(ic, AV_LOG_DEBUG, "After avformat_find_stream_info() pos: %"PRId64" bytes read:%"PRId64" seeks:%d frames:%d\n",
|
||||||
@@ -4137,6 +4232,8 @@ static void free_stream(AVStream **pst)
|
|||||||
av_bsf_free(&st->internal->bsfcs[i]);
|
av_bsf_free(&st->internal->bsfcs[i]);
|
||||||
av_freep(&st->internal->bsfcs);
|
av_freep(&st->internal->bsfcs);
|
||||||
}
|
}
|
||||||
|
av_bsf_free(&st->internal->extract_extradata.bsf);
|
||||||
|
av_packet_free(&st->internal->extract_extradata.pkt);
|
||||||
}
|
}
|
||||||
av_freep(&st->internal);
|
av_freep(&st->internal);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user