[FFmpeg-cvslog] Merge commit '549d0bdca53af7a6e0c612ab4b03baecf3a5878f'
James Almer
git at videolan.org
Sun Apr 23 02:32:33 EEST 2017
ffmpeg | branch: master | James Almer <jamrial at gmail.com> | Sat Apr 22 20:06:47 2017 -0300| [1fd76277708cf83572ba243e98f9e848c652f83d] | committer: James Almer
Merge commit '549d0bdca53af7a6e0c612ab4b03baecf3a5878f'
* commit '549d0bdca53af7a6e0c612ab4b03baecf3a5878f':
decode: be more explicit about storing the last packet properties
Also copy pkt->size in extract_packet_props(), as it's needed for
AVFrame.pkt_size
Merged-by: James Almer <jamrial at gmail.com>
> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=1fd76277708cf83572ba243e98f9e848c652f83d
---
libavcodec/decode.c | 46 +++++++++++++++++++++++++++-------------------
libavcodec/internal.h | 6 +++---
libavcodec/pthread_frame.c | 2 +-
libavcodec/rawdec.c | 4 ++--
libavcodec/utils.c | 8 ++++++++
5 files changed, 41 insertions(+), 25 deletions(-)
diff --git a/libavcodec/decode.c b/libavcodec/decode.c
index df9af689f2..5c8b4cbf56 100644
--- a/libavcodec/decode.c
+++ b/libavcodec/decode.c
@@ -118,6 +118,19 @@ fail2:
return 0;
}
+static int extract_packet_props(AVCodecInternal *avci, const AVPacket *pkt)
+{
+ int ret = 0;
+
+ av_packet_unref(avci->last_pkt_props);
+ if (pkt) {
+ ret = av_packet_copy_props(avci->last_pkt_props, pkt);
+ if (!ret)
+ avci->last_pkt_props->size = pkt->size; // HACK: Needed for ff_init_buffer_info().
+ }
+ return ret;
+}
+
static int unrefcount_frame(AVCodecInternal *avci, AVFrame *frame)
{
int ret;
@@ -394,7 +407,9 @@ int attribute_align_arg avcodec_decode_video2(AVCodecContext *avctx, AVFrame *pi
if ((avctx->coded_width || avctx->coded_height) && av_image_check_size2(avctx->coded_width, avctx->coded_height, avctx->max_pixels, AV_PIX_FMT_NONE, 0, avctx))
return AVERROR(EINVAL);
- avctx->internal->pkt = avpkt;
+ ret = extract_packet_props(avci, avpkt);
+ if (ret < 0)
+ return ret;
ret = apply_param_change(avctx, avpkt);
if (ret < 0)
return ret;
@@ -412,7 +427,9 @@ FF_ENABLE_DEPRECATION_WARNINGS
if (ret < 0)
goto fail;
- avctx->internal->pkt = &tmp;
+ ret = extract_packet_props(avci, &tmp);
+ if (ret < 0)
+ return ret;
if (HAVE_THREADS && avctx->active_thread_type & FF_THREAD_FRAME)
ret = ff_thread_decode_frame(avctx, picture, got_picture_ptr,
&tmp);
@@ -438,7 +455,6 @@ FF_ENABLE_DEPRECATION_WARNINGS
fail:
emms_c(); //needed to avoid an emms_c() call before every return;
- avctx->internal->pkt = NULL;
#if FF_API_MERGE_SD
if (did_split) {
av_packet_free_side_data(&tmp);
@@ -524,7 +540,9 @@ FF_ENABLE_DEPRECATION_WARNINGS
if (ret < 0)
goto fail;
- avctx->internal->pkt = &tmp;
+ ret = extract_packet_props(avci, &tmp);
+ if (ret < 0)
+ return ret;
if (HAVE_THREADS && avctx->active_thread_type & FF_THREAD_FRAME)
ret = ff_thread_decode_frame(avctx, frame, got_frame_ptr, &tmp);
else {
@@ -548,7 +566,7 @@ FF_ENABLE_DEPRECATION_WARNINGS
frame->sample_rate = avctx->sample_rate;
}
- side= av_packet_get_side_data(avctx->internal->pkt, AV_PKT_DATA_SKIP_SAMPLES, &side_size);
+ side= av_packet_get_side_data(avci->last_pkt_props, AV_PKT_DATA_SKIP_SAMPLES, &side_size);
if(side && side_size>=10) {
avctx->internal->skip_samples = AV_RL32(side) * avctx->internal->skip_samples_multiplier;
discard_padding = AV_RL32(side + 4);
@@ -630,7 +648,6 @@ FF_ENABLE_DEPRECATION_WARNINGS
}
}
fail:
- avctx->internal->pkt = NULL;
#if FF_API_MERGE_SD
if (did_split) {
av_packet_free_side_data(&tmp);
@@ -862,7 +879,9 @@ FF_ENABLE_DEPRECATION_WARNINGS
if (ret < 0) {
*got_sub_ptr = 0;
} else {
- avctx->internal->pkt = &pkt_recoded;
+ ret = extract_packet_props(avctx->internal, &pkt_recoded);
+ if (ret < 0)
+ return ret;
if (avctx->pkt_timebase.num && avpkt->pts != AV_NOPTS_VALUE)
sub->pts = av_rescale_q(avpkt->pts,
@@ -912,7 +931,6 @@ FF_ENABLE_DEPRECATION_WARNINGS
av_packet_unref(&pkt_recoded);
}
- avctx->internal->pkt = NULL;
}
#if FF_API_MERGE_SD
@@ -1292,7 +1310,7 @@ static int add_metadata_from_side_data(const AVPacket *avpkt, AVFrame *frame)
int ff_init_buffer_info(AVCodecContext *avctx, AVFrame *frame)
{
- const AVPacket *pkt = avctx->internal->pkt;
+ const AVPacket *pkt = avctx->internal->last_pkt_props;
int i;
static const struct {
enum AVPacketSideDataType packet;
@@ -1338,16 +1356,6 @@ FF_ENABLE_DEPRECATION_WARNINGS
} else {
frame->flags = (frame->flags & ~AV_FRAME_FLAG_DISCARD);
}
- } else {
- frame->pts = AV_NOPTS_VALUE;
-#if FF_API_PKT_PTS
-FF_DISABLE_DEPRECATION_WARNINGS
- frame->pkt_pts = AV_NOPTS_VALUE;
-FF_ENABLE_DEPRECATION_WARNINGS
-#endif
- av_frame_set_pkt_pos (frame, -1);
- av_frame_set_pkt_duration(frame, 0);
- av_frame_set_pkt_size (frame, -1);
}
frame->reordered_opaque = avctx->reordered_opaque;
diff --git a/libavcodec/internal.h b/libavcodec/internal.h
index e5f132a673..90a887332e 100644
--- a/libavcodec/internal.h
+++ b/libavcodec/internal.h
@@ -138,10 +138,10 @@ typedef struct AVCodecInternal {
void *thread_ctx;
/**
- * Current packet as passed into the decoder, to avoid having to pass the
- * packet into every function.
+ * Properties (timestamps+side data) extracted from the last packet passed
+ * for decoding.
*/
- const AVPacket *pkt;
+ AVPacket *last_pkt_props;
/**
* temporary buffer used for encoders to store their bitstream
diff --git a/libavcodec/pthread_frame.c b/libavcodec/pthread_frame.c
index 46c6292253..13d682842d 100644
--- a/libavcodec/pthread_frame.c
+++ b/libavcodec/pthread_frame.c
@@ -800,7 +800,7 @@ int ff_frame_thread_init(AVCodecContext *avctx)
}
*copy->internal = *src->internal;
copy->internal->thread_ctx = p;
- copy->internal->pkt = &p->avpkt;
+ copy->internal->last_pkt_props = &p->avpkt;
if (!i) {
src = copy;
diff --git a/libavcodec/rawdec.c b/libavcodec/rawdec.c
index e53eb2eacc..6dcb5f2e66 100644
--- a/libavcodec/rawdec.c
+++ b/libavcodec/rawdec.c
@@ -237,8 +237,8 @@ static int raw_decode(AVCodecContext *avctx, void *data, int *got_frame,
if (res < 0)
return res;
- av_frame_set_pkt_pos (frame, avctx->internal->pkt->pos);
- av_frame_set_pkt_duration(frame, avctx->internal->pkt->duration);
+ av_frame_set_pkt_pos (frame, avctx->internal->last_pkt_props->pos);
+ av_frame_set_pkt_duration(frame, avctx->internal->last_pkt_props->duration);
if (context->tff >= 0) {
frame->interlaced_frame = 1;
diff --git a/libavcodec/utils.c b/libavcodec/utils.c
index 56e58cc426..6a68971d68 100644
--- a/libavcodec/utils.c
+++ b/libavcodec/utils.c
@@ -684,6 +684,12 @@ int attribute_align_arg avcodec_open2(AVCodecContext *avctx, const AVCodec *code
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;
+ }
+
avctx->internal->skip_samples_multiplier = 1;
if (codec->priv_data_size > 0) {
@@ -1110,6 +1116,7 @@ FF_ENABLE_DEPRECATION_WARNINGS
av_frame_free(&avctx->internal->to_free);
av_frame_free(&avctx->internal->buffer_frame);
av_packet_free(&avctx->internal->buffer_pkt);
+ av_packet_free(&avctx->internal->last_pkt_props);
av_freep(&avctx->internal->pool);
}
av_freep(&avctx->internal);
@@ -1158,6 +1165,7 @@ av_cold int avcodec_close(AVCodecContext *avctx)
av_frame_free(&avctx->internal->to_free);
av_frame_free(&avctx->internal->buffer_frame);
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++)
av_buffer_pool_uninit(&pool->pools[i]);
av_freep(&avctx->internal->pool);
======================================================================
diff --cc libavcodec/decode.c
index df9af689f2,b02278d3a6..5c8b4cbf56
--- a/libavcodec/decode.c
+++ b/libavcodec/decode.c
@@@ -118,6 -99,14 +118,19 @@@ fail2
return 0;
}
+ static int extract_packet_props(AVCodecInternal *avci, const AVPacket *pkt)
+ {
++ int ret = 0;
++
+ av_packet_unref(avci->last_pkt_props);
- if (pkt)
- return av_packet_copy_props(avci->last_pkt_props, pkt);
- return 0;
++ if (pkt) {
++ ret = av_packet_copy_props(avci->last_pkt_props, pkt);
++ if (!ret)
++ avci->last_pkt_props->size = pkt->size; // HACK: Needed for ff_init_buffer_info().
++ }
++ return ret;
+ }
+
static int unrefcount_frame(AVCodecInternal *avci, AVFrame *frame)
{
int ret;
@@@ -390,11 -312,10 +403,13 @@@ int attribute_align_arg avcodec_decode_
return AVERROR(ENOSYS);
}
+ *got_picture_ptr = 0;
+ if ((avctx->coded_width || avctx->coded_height) && av_image_check_size2(avctx->coded_width, avctx->coded_height, avctx->max_pixels, AV_PIX_FMT_NONE, 0, avctx))
+ return AVERROR(EINVAL);
+
- avctx->internal->pkt = avpkt;
+ ret = extract_packet_props(avci, avpkt);
+ if (ret < 0)
+ return ret;
-
ret = apply_param_change(avctx, avpkt);
if (ret < 0)
return ret;
@@@ -403,52 -324,25 +418,53 @@@
if ((avctx->codec->capabilities & AV_CODEC_CAP_DELAY) || avpkt->size ||
(avctx->active_thread_type & FF_THREAD_FRAME)) {
+#if FF_API_MERGE_SD
+FF_DISABLE_DEPRECATION_WARNINGS
+ int did_split = av_packet_split_side_data(&tmp);
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif
+ ret = apply_param_change(avctx, &tmp);
+ if (ret < 0)
+ goto fail;
+
- avctx->internal->pkt = &tmp;
++ ret = extract_packet_props(avci, &tmp);
++ if (ret < 0)
++ return ret;
if (HAVE_THREADS && avctx->active_thread_type & FF_THREAD_FRAME)
ret = ff_thread_decode_frame(avctx, picture, got_picture_ptr,
- avpkt);
+ &tmp);
else {
ret = avctx->codec->decode(avctx, picture, got_picture_ptr,
- avpkt);
+ &tmp);
if (!(avctx->codec->caps_internal & FF_CODEC_CAP_SETS_PKT_DTS))
picture->pkt_dts = avpkt->dts;
+
+ if(!avctx->has_b_frames){
+ av_frame_set_pkt_pos(picture, avpkt->pos);
+ }
+ //FIXME these should be under if(!avctx->has_b_frames)
/* get_buffer is supposed to set frame parameters */
if (!(avctx->codec->capabilities & AV_CODEC_CAP_DR1)) {
- picture->sample_aspect_ratio = avctx->sample_aspect_ratio;
- picture->width = avctx->width;
- picture->height = avctx->height;
- picture->format = avctx->pix_fmt;
+ if (!picture->sample_aspect_ratio.num) picture->sample_aspect_ratio = avctx->sample_aspect_ratio;
+ if (!picture->width) picture->width = avctx->width;
+ if (!picture->height) picture->height = avctx->height;
+ if (picture->format == AV_PIX_FMT_NONE) picture->format = avctx->pix_fmt;
}
}
+fail:
emms_c(); //needed to avoid an emms_c() call before every return;
- avctx->internal->pkt = NULL;
+#if FF_API_MERGE_SD
+ if (did_split) {
+ av_packet_free_side_data(&tmp);
+ if(ret == tmp.size)
+ ret = avpkt->size;
+ }
+#endif
+ if (picture->flags & AV_FRAME_FLAG_DISCARD) {
+ *got_picture_ptr = 0;
+ }
if (*got_picture_ptr) {
if (!avctx->refcounted_frames) {
int err = unrefcount_frame(avci, picture);
@@@ -507,139 -394,14 +523,140 @@@ int attribute_align_arg avcodec_decode_
av_frame_unref(frame);
- if ((avctx->codec->capabilities & AV_CODEC_CAP_DELAY) || avpkt->size) {
- ret = avctx->codec->decode(avctx, frame, got_frame_ptr, avpkt);
+ if ((avctx->codec->capabilities & AV_CODEC_CAP_DELAY) || avpkt->size || (avctx->active_thread_type & FF_THREAD_FRAME)) {
+ uint8_t *side;
+ int side_size;
+ uint32_t discard_padding = 0;
+ uint8_t skip_reason = 0;
+ uint8_t discard_reason = 0;
+ // copy to ensure we do not change avpkt
+ AVPacket tmp = *avpkt;
+#if FF_API_MERGE_SD
+FF_DISABLE_DEPRECATION_WARNINGS
+ int did_split = av_packet_split_side_data(&tmp);
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif
+ ret = apply_param_change(avctx, &tmp);
+ if (ret < 0)
+ goto fail;
+
- avctx->internal->pkt = &tmp;
++ ret = extract_packet_props(avci, &tmp);
++ if (ret < 0)
++ return ret;
+ if (HAVE_THREADS && avctx->active_thread_type & FF_THREAD_FRAME)
+ ret = ff_thread_decode_frame(avctx, frame, got_frame_ptr, &tmp);
+ else {
+ ret = avctx->codec->decode(avctx, frame, got_frame_ptr, &tmp);
+ av_assert0(ret <= tmp.size);
+ frame->pkt_dts = avpkt->dts;
+ }
if (ret >= 0 && *got_frame_ptr) {
avctx->frame_number++;
- frame->pkt_dts = avpkt->dts;
+ av_frame_set_best_effort_timestamp(frame,
+ guess_correct_pts(avctx,
+ frame->pts,
+ frame->pkt_dts));
if (frame->format == AV_SAMPLE_FMT_NONE)
frame->format = avctx->sample_fmt;
+ if (!frame->channel_layout)
+ frame->channel_layout = avctx->channel_layout;
+ if (!av_frame_get_channels(frame))
+ av_frame_set_channels(frame, avctx->channels);
+ if (!frame->sample_rate)
+ frame->sample_rate = avctx->sample_rate;
+ }
+
- side= av_packet_get_side_data(avctx->internal->pkt, AV_PKT_DATA_SKIP_SAMPLES, &side_size);
++ side= av_packet_get_side_data(avci->last_pkt_props, AV_PKT_DATA_SKIP_SAMPLES, &side_size);
+ if(side && side_size>=10) {
+ avctx->internal->skip_samples = AV_RL32(side) * avctx->internal->skip_samples_multiplier;
+ discard_padding = AV_RL32(side + 4);
+ av_log(avctx, AV_LOG_DEBUG, "skip %d / discard %d samples due to side data\n",
+ avctx->internal->skip_samples, (int)discard_padding);
+ skip_reason = AV_RL8(side + 8);
+ discard_reason = AV_RL8(side + 9);
+ }
+
+ if ((frame->flags & AV_FRAME_FLAG_DISCARD) && *got_frame_ptr &&
+ !(avctx->flags2 & AV_CODEC_FLAG2_SKIP_MANUAL)) {
+ avctx->internal->skip_samples = FFMAX(0, avctx->internal->skip_samples - frame->nb_samples);
+ *got_frame_ptr = 0;
+ }
+
+ if (avctx->internal->skip_samples > 0 && *got_frame_ptr &&
+ !(avctx->flags2 & AV_CODEC_FLAG2_SKIP_MANUAL)) {
+ if(frame->nb_samples <= avctx->internal->skip_samples){
+ *got_frame_ptr = 0;
+ avctx->internal->skip_samples -= frame->nb_samples;
+ av_log(avctx, AV_LOG_DEBUG, "skip whole frame, skip left: %d\n",
+ avctx->internal->skip_samples);
+ } else {
+ av_samples_copy(frame->extended_data, frame->extended_data, 0, avctx->internal->skip_samples,
+ frame->nb_samples - avctx->internal->skip_samples, avctx->channels, frame->format);
+ if(avctx->pkt_timebase.num && avctx->sample_rate) {
+ int64_t diff_ts = av_rescale_q(avctx->internal->skip_samples,
+ (AVRational){1, avctx->sample_rate},
+ avctx->pkt_timebase);
+ if(frame->pts!=AV_NOPTS_VALUE)
+ frame->pts += diff_ts;
+#if FF_API_PKT_PTS
+FF_DISABLE_DEPRECATION_WARNINGS
+ if(frame->pkt_pts!=AV_NOPTS_VALUE)
+ frame->pkt_pts += diff_ts;
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif
+ if(frame->pkt_dts!=AV_NOPTS_VALUE)
+ frame->pkt_dts += diff_ts;
+ if (av_frame_get_pkt_duration(frame) >= diff_ts)
+ av_frame_set_pkt_duration(frame, av_frame_get_pkt_duration(frame) - diff_ts);
+ } else {
+ av_log(avctx, AV_LOG_WARNING, "Could not update timestamps for skipped samples.\n");
+ }
+ av_log(avctx, AV_LOG_DEBUG, "skip %d/%d samples\n",
+ avctx->internal->skip_samples, frame->nb_samples);
+ frame->nb_samples -= avctx->internal->skip_samples;
+ avctx->internal->skip_samples = 0;
+ }
+ }
+
+ if (discard_padding > 0 && discard_padding <= frame->nb_samples && *got_frame_ptr &&
+ !(avctx->flags2 & AV_CODEC_FLAG2_SKIP_MANUAL)) {
+ if (discard_padding == frame->nb_samples) {
+ *got_frame_ptr = 0;
+ } else {
+ if(avctx->pkt_timebase.num && avctx->sample_rate) {
+ int64_t diff_ts = av_rescale_q(frame->nb_samples - discard_padding,
+ (AVRational){1, avctx->sample_rate},
+ avctx->pkt_timebase);
+ av_frame_set_pkt_duration(frame, diff_ts);
+ } else {
+ av_log(avctx, AV_LOG_WARNING, "Could not update timestamps for discarded samples.\n");
+ }
+ av_log(avctx, AV_LOG_DEBUG, "discard %d/%d samples\n",
+ (int)discard_padding, frame->nb_samples);
+ frame->nb_samples -= discard_padding;
+ }
+ }
+
+ if ((avctx->flags2 & AV_CODEC_FLAG2_SKIP_MANUAL) && *got_frame_ptr) {
+ AVFrameSideData *fside = av_frame_new_side_data(frame, AV_FRAME_DATA_SKIP_SAMPLES, 10);
+ if (fside) {
+ AV_WL32(fside->data, avctx->internal->skip_samples);
+ AV_WL32(fside->data + 4, discard_padding);
+ AV_WL8(fside->data + 8, skip_reason);
+ AV_WL8(fside->data + 9, discard_reason);
+ avctx->internal->skip_samples = 0;
+ }
+ }
+fail:
- avctx->internal->pkt = NULL;
+#if FF_API_MERGE_SD
+ if (did_split) {
+ av_packet_free_side_data(&tmp);
+ if(ret == tmp.size)
+ ret = avpkt->size;
+ }
+#endif
+ if (ret >= 0 && *got_frame_ptr) {
if (!avctx->refcounted_frames) {
int err = unrefcount_frame(avci, frame);
if (err < 0)
@@@ -821,112 -419,16 +838,113 @@@ int avcodec_decode_subtitle2(AVCodecCon
int *got_sub_ptr,
AVPacket *avpkt)
{
- int ret;
+ int i, ret = 0;
- ret = extract_packet_props(avctx->internal, avpkt);
- if (ret < 0)
- return ret;
+ if (!avpkt->data && avpkt->size) {
+ av_log(avctx, AV_LOG_ERROR, "invalid packet: NULL data, size != 0\n");
+ return AVERROR(EINVAL);
+ }
+ if (!avctx->codec)
+ return AVERROR(EINVAL);
+ if (avctx->codec->type != AVMEDIA_TYPE_SUBTITLE) {
+ av_log(avctx, AV_LOG_ERROR, "Invalid media type for subtitles\n");
+ return AVERROR(EINVAL);
+ }
*got_sub_ptr = 0;
- ret = avctx->codec->decode(avctx, sub, got_sub_ptr, avpkt);
- if (*got_sub_ptr)
- avctx->frame_number++;
+ get_subtitle_defaults(sub);
+
+ if ((avctx->codec->capabilities & AV_CODEC_CAP_DELAY) || avpkt->size) {
+ AVPacket pkt_recoded;
+ AVPacket tmp = *avpkt;
+#if FF_API_MERGE_SD
+FF_DISABLE_DEPRECATION_WARNINGS
+ int did_split = av_packet_split_side_data(&tmp);
+ //apply_param_change(avctx, &tmp);
+
+ if (did_split) {
+ /* FFMIN() prevents overflow in case the packet wasn't allocated with
+ * proper padding.
+ * If the side data is smaller than the buffer padding size, the
+ * remaining bytes should have already been filled with zeros by the
+ * original packet allocation anyway. */
+ memset(tmp.data + tmp.size, 0,
+ FFMIN(avpkt->size - tmp.size, AV_INPUT_BUFFER_PADDING_SIZE));
+ }
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif
+
+ pkt_recoded = tmp;
+ ret = recode_subtitle(avctx, &pkt_recoded, &tmp);
+ if (ret < 0) {
+ *got_sub_ptr = 0;
+ } else {
- avctx->internal->pkt = &pkt_recoded;
++ ret = extract_packet_props(avctx->internal, &pkt_recoded);
++ if (ret < 0)
++ return ret;
+
+ if (avctx->pkt_timebase.num && avpkt->pts != AV_NOPTS_VALUE)
+ sub->pts = av_rescale_q(avpkt->pts,
+ avctx->pkt_timebase, AV_TIME_BASE_Q);
+ ret = avctx->codec->decode(avctx, sub, got_sub_ptr, &pkt_recoded);
+ av_assert1((ret >= 0) >= !!*got_sub_ptr &&
+ !!*got_sub_ptr >= !!sub->num_rects);
+
+#if FF_API_ASS_TIMING
+ if (avctx->sub_text_format == FF_SUB_TEXT_FMT_ASS_WITH_TIMINGS
+ && *got_sub_ptr && sub->num_rects) {
+ const AVRational tb = avctx->pkt_timebase.num ? avctx->pkt_timebase
+ : avctx->time_base;
+ int err = convert_sub_to_old_ass_form(sub, avpkt, tb);
+ if (err < 0)
+ ret = err;
+ }
+#endif
+
+ if (sub->num_rects && !sub->end_display_time && avpkt->duration &&
+ avctx->pkt_timebase.num) {
+ AVRational ms = { 1, 1000 };
+ sub->end_display_time = av_rescale_q(avpkt->duration,
+ avctx->pkt_timebase, ms);
+ }
+
+ if (avctx->codec_descriptor->props & AV_CODEC_PROP_BITMAP_SUB)
+ sub->format = 0;
+ else if (avctx->codec_descriptor->props & AV_CODEC_PROP_TEXT_SUB)
+ sub->format = 1;
+
+ for (i = 0; i < sub->num_rects; i++) {
+ if (sub->rects[i]->ass && !utf8_check(sub->rects[i]->ass)) {
+ av_log(avctx, AV_LOG_ERROR,
+ "Invalid UTF-8 in decoded subtitles text; "
+ "maybe missing -sub_charenc option\n");
+ avsubtitle_free(sub);
+ ret = AVERROR_INVALIDDATA;
+ break;
+ }
+ }
+
+ if (tmp.data != pkt_recoded.data) { // did we recode?
+ /* prevent from destroying side data from original packet */
+ pkt_recoded.side_data = NULL;
+ pkt_recoded.side_data_elems = 0;
+
+ av_packet_unref(&pkt_recoded);
+ }
- avctx->internal->pkt = NULL;
+ }
+
+#if FF_API_MERGE_SD
+ if (did_split) {
+ av_packet_free_side_data(&tmp);
+ if(ret == tmp.size)
+ ret = avpkt->size;
+ }
+#endif
+
+ if (*got_sub_ptr)
+ avctx->frame_number++;
+ }
+
return ret;
}
@@@ -1278,93 -753,68 +1296,83 @@@ int avcodec_default_get_buffer2(AVCodec
}
}
-int ff_decode_frame_props(AVCodecContext *avctx, AVFrame *frame)
+static int add_metadata_from_side_data(const AVPacket *avpkt, AVFrame *frame)
{
- AVPacket *pkt = avctx->internal->last_pkt_props;
+ int size;
+ const uint8_t *side_metadata;
+
+ AVDictionary **frame_md = avpriv_frame_get_metadatap(frame);
+
+ side_metadata = av_packet_get_side_data(avpkt,
+ AV_PKT_DATA_STRINGS_METADATA, &size);
+ return av_packet_unpack_dictionary(side_metadata, size, frame_md);
+}
+
+int ff_init_buffer_info(AVCodecContext *avctx, AVFrame *frame)
+{
- const AVPacket *pkt = avctx->internal->pkt;
++ const AVPacket *pkt = avctx->internal->last_pkt_props;
int i;
- struct {
+ static const struct {
enum AVPacketSideDataType packet;
enum AVFrameSideDataType frame;
} sd[] = {
- { AV_PKT_DATA_REPLAYGAIN , AV_FRAME_DATA_REPLAYGAIN },
- { AV_PKT_DATA_DISPLAYMATRIX, AV_FRAME_DATA_DISPLAYMATRIX },
- { AV_PKT_DATA_SPHERICAL, AV_FRAME_DATA_SPHERICAL },
- { AV_PKT_DATA_STEREO3D, AV_FRAME_DATA_STEREO3D },
- { AV_PKT_DATA_AUDIO_SERVICE_TYPE, AV_FRAME_DATA_AUDIO_SERVICE_TYPE },
+ { AV_PKT_DATA_REPLAYGAIN , AV_FRAME_DATA_REPLAYGAIN },
+ { AV_PKT_DATA_DISPLAYMATRIX, AV_FRAME_DATA_DISPLAYMATRIX },
+ { AV_PKT_DATA_SPHERICAL, AV_FRAME_DATA_SPHERICAL },
+ { AV_PKT_DATA_STEREO3D, AV_FRAME_DATA_STEREO3D },
+ { AV_PKT_DATA_AUDIO_SERVICE_TYPE, AV_FRAME_DATA_AUDIO_SERVICE_TYPE },
+ { AV_PKT_DATA_MASTERING_DISPLAY_METADATA, AV_FRAME_DATA_MASTERING_DISPLAY_METADATA },
+ { AV_PKT_DATA_CONTENT_LIGHT_LEVEL, AV_FRAME_DATA_CONTENT_LIGHT_LEVEL },
};
- frame->color_primaries = avctx->color_primaries;
- frame->color_trc = avctx->color_trc;
- frame->colorspace = avctx->colorspace;
- frame->color_range = avctx->color_range;
- frame->chroma_location = avctx->chroma_sample_location;
-
- frame->reordered_opaque = avctx->reordered_opaque;
-
+ if (pkt) {
+ frame->pts = pkt->pts;
#if FF_API_PKT_PTS
FF_DISABLE_DEPRECATION_WARNINGS
- frame->pkt_pts = pkt->pts;
+ frame->pkt_pts = pkt->pts;
FF_ENABLE_DEPRECATION_WARNINGS
#endif
- frame->pts = pkt->pts;
-
- for (i = 0; i < FF_ARRAY_ELEMS(sd); i++) {
- int size;
- uint8_t *packet_sd = av_packet_get_side_data(pkt, sd[i].packet, &size);
- if (packet_sd) {
- AVFrameSideData *frame_sd = av_frame_new_side_data(frame,
- sd[i].frame,
- size);
- if (!frame_sd)
- return AVERROR(ENOMEM);
+ av_frame_set_pkt_pos (frame, pkt->pos);
+ av_frame_set_pkt_duration(frame, pkt->duration);
+ av_frame_set_pkt_size (frame, pkt->size);
+
+ for (i = 0; i < FF_ARRAY_ELEMS(sd); i++) {
+ int size;
+ uint8_t *packet_sd = av_packet_get_side_data(pkt, sd[i].packet, &size);
+ if (packet_sd) {
+ AVFrameSideData *frame_sd = av_frame_new_side_data(frame,
+ sd[i].frame,
+ size);
+ if (!frame_sd)
+ return AVERROR(ENOMEM);
+
+ memcpy(frame_sd->data, packet_sd, size);
+ }
+ }
+ add_metadata_from_side_data(pkt, frame);
- memcpy(frame_sd->data, packet_sd, size);
+ if (pkt->flags & AV_PKT_FLAG_DISCARD) {
+ frame->flags |= AV_FRAME_FLAG_DISCARD;
+ } else {
+ frame->flags = (frame->flags & ~AV_FRAME_FLAG_DISCARD);
}
- } else {
- frame->pts = AV_NOPTS_VALUE;
- #if FF_API_PKT_PTS
- FF_DISABLE_DEPRECATION_WARNINGS
- frame->pkt_pts = AV_NOPTS_VALUE;
- FF_ENABLE_DEPRECATION_WARNINGS
- #endif
- av_frame_set_pkt_pos (frame, -1);
- av_frame_set_pkt_duration(frame, 0);
- av_frame_set_pkt_size (frame, -1);
}
+ frame->reordered_opaque = avctx->reordered_opaque;
- return 0;
-}
-
-int ff_get_buffer(AVCodecContext *avctx, AVFrame *frame, int flags)
-{
- const AVHWAccel *hwaccel = avctx->hwaccel;
- int override_dimensions = 1;
- int ret;
-
- switch (avctx->codec_type) {
+ if (frame->color_primaries == AVCOL_PRI_UNSPECIFIED)
+ frame->color_primaries = avctx->color_primaries;
+ if (frame->color_trc == AVCOL_TRC_UNSPECIFIED)
+ frame->color_trc = avctx->color_trc;
+ if (av_frame_get_colorspace(frame) == AVCOL_SPC_UNSPECIFIED)
+ av_frame_set_colorspace(frame, avctx->colorspace);
+ if (av_frame_get_color_range(frame) == AVCOL_RANGE_UNSPECIFIED)
+ av_frame_set_color_range(frame, avctx->color_range);
+ if (frame->chroma_location == AVCHROMA_LOC_UNSPECIFIED)
+ frame->chroma_location = avctx->chroma_sample_location;
+
+ switch (avctx->codec->type) {
case AVMEDIA_TYPE_VIDEO:
- if (frame->width <= 0 || frame->height <= 0) {
- frame->width = FFMAX(avctx->width, avctx->coded_width);
- frame->height = FFMAX(avctx->height, avctx->coded_height);
- override_dimensions = 0;
- }
- if (frame->format < 0)
- frame->format = avctx->pix_fmt;
+ frame->format = avctx->pix_fmt;
if (!frame->sample_aspect_ratio.num)
frame->sample_aspect_ratio = avctx->sample_aspect_ratio;
diff --cc libavcodec/internal.h
index e5f132a673,2ca7a45e81..90a887332e
--- a/libavcodec/internal.h
+++ b/libavcodec/internal.h
@@@ -138,25 -131,12 +138,25 @@@ typedef struct AVCodecInternal
void *thread_ctx;
/**
- * Current packet as passed into the decoder, to avoid having to pass the
- * packet into every function.
+ * Properties (timestamps+side data) extracted from the last packet passed
+ * for decoding.
*/
- const AVPacket *pkt;
+ AVPacket *last_pkt_props;
/**
+ * temporary buffer used for encoders to store their bitstream
+ */
+ uint8_t *byte_buffer;
+ unsigned int byte_buffer_size;
+
+ void *frame_thread_encoder;
+
+ /**
+ * Number of audio samples to skip at the start of the next decoded frame
+ */
+ int skip_samples;
+
+ /**
* hwaccel-specific private data
*/
void *hwaccel_priv_data;
diff --cc libavcodec/rawdec.c
index e53eb2eacc,284c3451d0..6dcb5f2e66
--- a/libavcodec/rawdec.c
+++ b/libavcodec/rawdec.c
@@@ -237,19 -156,12 +237,19 @@@ static int raw_decode(AVCodecContext *a
if (res < 0)
return res;
- av_frame_set_pkt_pos (frame, avctx->internal->pkt->pos);
- av_frame_set_pkt_duration(frame, avctx->internal->pkt->duration);
- if (buf_size < context->frame_size - (avctx->pix_fmt == AV_PIX_FMT_PAL8 ?
- AVPALETTE_SIZE : 0))
- return -1;
++ av_frame_set_pkt_pos (frame, avctx->internal->last_pkt_props->pos);
++ av_frame_set_pkt_duration(frame, avctx->internal->last_pkt_props->duration);
+
+ if (context->tff >= 0) {
+ frame->interlaced_frame = 1;
+ frame->top_field_first = context->tff;
+ }
+
+ if ((res = av_image_check_size(avctx->width, avctx->height, 0, avctx)) < 0)
+ return res;
if (need_copy)
- frame->buf[0] = av_buffer_alloc(context->frame_size);
+ frame->buf[0] = av_buffer_alloc(FFMAX(context->frame_size, buf_size));
else
frame->buf[0] = av_buffer_ref(avpkt->buf);
if (!frame->buf[0])
diff --cc libavcodec/utils.c
index 56e58cc426,b569b48f7a..6a68971d68
--- a/libavcodec/utils.c
+++ b/libavcodec/utils.c
@@@ -684,8 -433,12 +684,14 @@@ int attribute_align_arg avcodec_open2(A
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;
+ }
+
+ avctx->internal->skip_samples_multiplier = 1;
+
if (codec->priv_data_size > 0) {
if (!avctx->priv_data) {
avctx->priv_data = av_mallocz(codec->priv_data_size);
More information about the ffmpeg-cvslog
mailing list