You've already forked FFmpeg
mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2025-08-15 14:13:16 +02:00
decode: be more explicit about storing the last packet properties
The current code stores a pointer to the packet passed to the decoder, which is then used during get_buffer() for timestamps and side data passthrough. However, since this is a pointer to user data which we do not own, storing it is potentially dangerous. It is also ill defined for the new decoding API with split input/output. Fix this problem by making an explicit internally owned copy of the packet properties.
This commit is contained in:
@@ -99,6 +99,14 @@ fail2:
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int extract_packet_props(AVCodecInternal *avci, const AVPacket *pkt)
|
||||||
|
{
|
||||||
|
av_packet_unref(avci->last_pkt_props);
|
||||||
|
if (pkt)
|
||||||
|
return av_packet_copy_props(avci->last_pkt_props, pkt);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int unrefcount_frame(AVCodecInternal *avci, AVFrame *frame)
|
static int unrefcount_frame(AVCodecInternal *avci, AVFrame *frame)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
@@ -304,7 +312,10 @@ int attribute_align_arg avcodec_decode_video2(AVCodecContext *avctx, AVFrame *pi
|
|||||||
return AVERROR(ENOSYS);
|
return AVERROR(ENOSYS);
|
||||||
}
|
}
|
||||||
|
|
||||||
avctx->internal->pkt = avpkt;
|
ret = extract_packet_props(avci, avpkt);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
ret = apply_param_change(avctx, avpkt);
|
ret = apply_param_change(avctx, avpkt);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
@@ -368,7 +379,9 @@ int attribute_align_arg avcodec_decode_audio4(AVCodecContext *avctx,
|
|||||||
return AVERROR(ENOSYS);
|
return AVERROR(ENOSYS);
|
||||||
}
|
}
|
||||||
|
|
||||||
avctx->internal->pkt = avpkt;
|
ret = extract_packet_props(avci, avpkt);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
if (!avpkt->data && avpkt->size) {
|
if (!avpkt->data && avpkt->size) {
|
||||||
av_log(avctx, AV_LOG_ERROR, "invalid packet: NULL data, size != 0\n");
|
av_log(avctx, AV_LOG_ERROR, "invalid packet: NULL data, size != 0\n");
|
||||||
@@ -408,7 +421,10 @@ int avcodec_decode_subtitle2(AVCodecContext *avctx, AVSubtitle *sub,
|
|||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
avctx->internal->pkt = avpkt;
|
ret = extract_packet_props(avctx->internal, avpkt);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
*got_sub_ptr = 0;
|
*got_sub_ptr = 0;
|
||||||
ret = avctx->codec->decode(avctx, sub, got_sub_ptr, avpkt);
|
ret = avctx->codec->decode(avctx, sub, got_sub_ptr, avpkt);
|
||||||
if (*got_sub_ptr)
|
if (*got_sub_ptr)
|
||||||
@@ -739,7 +755,7 @@ int avcodec_default_get_buffer2(AVCodecContext *avctx, AVFrame *frame, int flags
|
|||||||
|
|
||||||
int ff_decode_frame_props(AVCodecContext *avctx, AVFrame *frame)
|
int ff_decode_frame_props(AVCodecContext *avctx, AVFrame *frame)
|
||||||
{
|
{
|
||||||
AVPacket *pkt = avctx->internal->pkt;
|
AVPacket *pkt = avctx->internal->last_pkt_props;
|
||||||
int i;
|
int i;
|
||||||
struct {
|
struct {
|
||||||
enum AVPacketSideDataType packet;
|
enum AVPacketSideDataType packet;
|
||||||
@@ -759,15 +775,6 @@ int ff_decode_frame_props(AVCodecContext *avctx, AVFrame *frame)
|
|||||||
frame->chroma_location = avctx->chroma_sample_location;
|
frame->chroma_location = avctx->chroma_sample_location;
|
||||||
|
|
||||||
frame->reordered_opaque = avctx->reordered_opaque;
|
frame->reordered_opaque = avctx->reordered_opaque;
|
||||||
if (!pkt) {
|
|
||||||
#if FF_API_PKT_PTS
|
|
||||||
FF_DISABLE_DEPRECATION_WARNINGS
|
|
||||||
frame->pkt_pts = AV_NOPTS_VALUE;
|
|
||||||
FF_ENABLE_DEPRECATION_WARNINGS
|
|
||||||
#endif
|
|
||||||
frame->pts = AV_NOPTS_VALUE;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if FF_API_PKT_PTS
|
#if FF_API_PKT_PTS
|
||||||
FF_DISABLE_DEPRECATION_WARNINGS
|
FF_DISABLE_DEPRECATION_WARNINGS
|
||||||
|
@@ -131,10 +131,10 @@ typedef struct AVCodecInternal {
|
|||||||
void *thread_ctx;
|
void *thread_ctx;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Current packet as passed into the decoder, to avoid having to pass the
|
* Properties (timestamps+side data) extracted from the last packet passed
|
||||||
* packet into every function.
|
* for decoding.
|
||||||
*/
|
*/
|
||||||
AVPacket *pkt;
|
AVPacket *last_pkt_props;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* hwaccel-specific private data
|
* hwaccel-specific private data
|
||||||
|
@@ -656,7 +656,7 @@ int ff_frame_thread_init(AVCodecContext *avctx)
|
|||||||
}
|
}
|
||||||
*copy->internal = *src->internal;
|
*copy->internal = *src->internal;
|
||||||
copy->internal->thread_ctx = p;
|
copy->internal->thread_ctx = p;
|
||||||
copy->internal->pkt = &p->avpkt;
|
copy->internal->last_pkt_props = &p->avpkt;
|
||||||
|
|
||||||
if (!i) {
|
if (!i) {
|
||||||
src = copy;
|
src = copy;
|
||||||
|
@@ -433,6 +433,12 @@ int attribute_align_arg avcodec_open2(AVCodecContext *avctx, const AVCodec *code
|
|||||||
goto free_and_end;
|
goto free_and_end;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
avctx->internal->last_pkt_props = av_packet_alloc();
|
||||||
|
if (!avctx->internal->last_pkt_props) {
|
||||||
|
ret = AVERROR(ENOMEM);
|
||||||
|
goto free_and_end;
|
||||||
|
}
|
||||||
|
|
||||||
if (codec->priv_data_size > 0) {
|
if (codec->priv_data_size > 0) {
|
||||||
if (!avctx->priv_data) {
|
if (!avctx->priv_data) {
|
||||||
avctx->priv_data = av_mallocz(codec->priv_data_size);
|
avctx->priv_data = av_mallocz(codec->priv_data_size);
|
||||||
@@ -713,6 +719,7 @@ FF_ENABLE_DEPRECATION_WARNINGS
|
|||||||
av_frame_free(&avctx->internal->to_free);
|
av_frame_free(&avctx->internal->to_free);
|
||||||
av_frame_free(&avctx->internal->buffer_frame);
|
av_frame_free(&avctx->internal->buffer_frame);
|
||||||
av_packet_free(&avctx->internal->buffer_pkt);
|
av_packet_free(&avctx->internal->buffer_pkt);
|
||||||
|
av_packet_free(&avctx->internal->last_pkt_props);
|
||||||
av_freep(&avctx->internal->pool);
|
av_freep(&avctx->internal->pool);
|
||||||
}
|
}
|
||||||
av_freep(&avctx->internal);
|
av_freep(&avctx->internal);
|
||||||
@@ -753,6 +760,7 @@ av_cold int avcodec_close(AVCodecContext *avctx)
|
|||||||
av_frame_free(&avctx->internal->to_free);
|
av_frame_free(&avctx->internal->to_free);
|
||||||
av_frame_free(&avctx->internal->buffer_frame);
|
av_frame_free(&avctx->internal->buffer_frame);
|
||||||
av_packet_free(&avctx->internal->buffer_pkt);
|
av_packet_free(&avctx->internal->buffer_pkt);
|
||||||
|
av_packet_free(&avctx->internal->last_pkt_props);
|
||||||
for (i = 0; i < FF_ARRAY_ELEMS(pool->pools); i++)
|
for (i = 0; i < FF_ARRAY_ELEMS(pool->pools); i++)
|
||||||
av_buffer_pool_uninit(&pool->pools[i]);
|
av_buffer_pool_uninit(&pool->pools[i]);
|
||||||
av_freep(&avctx->internal->pool);
|
av_freep(&avctx->internal->pool);
|
||||||
|
Reference in New Issue
Block a user