Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/FFmpeg/FFmpeg.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cmdutils.c141
-rw-r--r--cmdutils.h43
-rw-r--r--ffmpeg.c146
-rw-r--r--ffmpeg.h3
-rw-r--r--ffplay.c79
5 files changed, 94 insertions, 318 deletions
diff --git a/cmdutils.c b/cmdutils.c
index 3a094f0b6a..9bbb837148 100644
--- a/cmdutils.c
+++ b/cmdutils.c
@@ -1826,144 +1826,3 @@ void *grow_array(void *array, int elem_size, int *size, int new_size)
}
return array;
}
-
-static int alloc_buffer(FrameBuffer **pool, AVCodecContext *s, FrameBuffer **pbuf)
-{
- const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(s->pix_fmt);
- FrameBuffer *buf;
- int i, ret;
- int pixel_size;
- int h_chroma_shift, v_chroma_shift;
- int edge = 32; // XXX should be avcodec_get_edge_width(), but that fails on svq1
- int w = s->width, h = s->height;
-
- if (!desc)
- return AVERROR(EINVAL);
- pixel_size = desc->comp[0].step_minus1 + 1;
-
- buf = av_mallocz(sizeof(*buf));
- if (!buf)
- return AVERROR(ENOMEM);
-
- avcodec_align_dimensions(s, &w, &h);
-
- if (!(s->flags & CODEC_FLAG_EMU_EDGE)) {
- w += 2*edge;
- h += 2*edge;
- }
-
- if ((ret = av_image_alloc(buf->base, buf->linesize, w, h,
- s->pix_fmt, 32)) < 0) {
- av_freep(&buf);
- av_log(s, AV_LOG_ERROR, "alloc_buffer: av_image_alloc() failed\n");
- return ret;
- }
-
- avcodec_get_chroma_sub_sample(s->pix_fmt, &h_chroma_shift, &v_chroma_shift);
- for (i = 0; i < FF_ARRAY_ELEMS(buf->data); i++) {
- const int h_shift = i==0 ? 0 : h_chroma_shift;
- const int v_shift = i==0 ? 0 : v_chroma_shift;
- if ((s->flags & CODEC_FLAG_EMU_EDGE) || !buf->linesize[i] || !buf->base[i])
- buf->data[i] = buf->base[i];
- else
- buf->data[i] = buf->base[i] +
- FFALIGN((buf->linesize[i]*edge >> v_shift) +
- (pixel_size*edge >> h_shift), 32);
- }
- buf->w = s->width;
- buf->h = s->height;
- buf->pix_fmt = s->pix_fmt;
- buf->pool = pool;
-
- *pbuf = buf;
- return 0;
-}
-
-int codec_get_buffer(AVCodecContext *s, AVFrame *frame)
-{
- FrameBuffer **pool = s->opaque;
- FrameBuffer *buf;
- int ret, i;
-
- if(av_image_check_size(s->width, s->height, 0, s) || s->pix_fmt<0) {
- av_log(s, AV_LOG_ERROR, "codec_get_buffer: image parameters invalid\n");
- return -1;
- }
-
- if (!*pool && (ret = alloc_buffer(pool, s, pool)) < 0)
- return ret;
-
- buf = *pool;
- *pool = buf->next;
- buf->next = NULL;
- if (buf->w != s->width || buf->h != s->height || buf->pix_fmt != s->pix_fmt) {
- av_freep(&buf->base[0]);
- av_free(buf);
- if ((ret = alloc_buffer(pool, s, &buf)) < 0)
- return ret;
- }
- av_assert0(!buf->refcount);
- buf->refcount++;
-
- frame->opaque = buf;
- frame->type = FF_BUFFER_TYPE_USER;
- frame->extended_data = frame->data;
-
- for (i = 0; i < FF_ARRAY_ELEMS(buf->data); i++) {
- frame->base[i] = buf->base[i]; // XXX h264.c uses base though it shouldn't
- frame->data[i] = buf->data[i];
- frame->linesize[i] = buf->linesize[i];
- }
-
- return 0;
-}
-
-static void unref_buffer(FrameBuffer *buf)
-{
- FrameBuffer **pool = buf->pool;
-
- av_assert0(buf->refcount > 0);
- buf->refcount--;
- if (!buf->refcount) {
- FrameBuffer *tmp;
- for(tmp= *pool; tmp; tmp= tmp->next)
- av_assert1(tmp != buf);
-
- buf->next = *pool;
- *pool = buf;
- }
-}
-
-void codec_release_buffer(AVCodecContext *s, AVFrame *frame)
-{
- FrameBuffer *buf = frame->opaque;
- int i;
-
- if(frame->type!=FF_BUFFER_TYPE_USER) {
- avcodec_default_release_buffer(s, frame);
- return;
- }
-
- for (i = 0; i < FF_ARRAY_ELEMS(frame->data); i++)
- frame->data[i] = NULL;
-
- unref_buffer(buf);
-}
-
-void filter_release_buffer(AVFilterBuffer *fb)
-{
- FrameBuffer *buf = fb->priv;
- av_free(fb);
- unref_buffer(buf);
-}
-
-void free_buffer_pool(FrameBuffer **pool)
-{
- FrameBuffer *buf = *pool;
- while (buf) {
- *pool = buf->next;
- av_freep(&buf->base[0]);
- av_free(buf);
- buf = *pool;
- }
-}
diff --git a/cmdutils.h b/cmdutils.h
index 08c92ce6ee..cce516d1ec 100644
--- a/cmdutils.h
+++ b/cmdutils.h
@@ -520,49 +520,6 @@ void *grow_array(void *array, int elem_size, int *size, int new_size);
#define GROW_ARRAY(array, nb_elems)\
array = grow_array(array, sizeof(*array), &nb_elems, nb_elems + 1)
-typedef struct FrameBuffer {
- uint8_t *base[4];
- uint8_t *data[4];
- int linesize[4];
-
- int h, w;
- enum AVPixelFormat pix_fmt;
-
- int refcount;
- struct FrameBuffer **pool; ///< head of the buffer pool
- struct FrameBuffer *next;
-} FrameBuffer;
-
-/**
- * Get a frame from the pool. This is intended to be used as a callback for
- * AVCodecContext.get_buffer.
- *
- * @param s codec context. s->opaque must be a pointer to the head of the
- * buffer pool.
- * @param frame frame->opaque will be set to point to the FrameBuffer
- * containing the frame data.
- */
-int codec_get_buffer(AVCodecContext *s, AVFrame *frame);
-
-/**
- * A callback to be used for AVCodecContext.release_buffer along with
- * codec_get_buffer().
- */
-void codec_release_buffer(AVCodecContext *s, AVFrame *frame);
-
-/**
- * A callback to be used for AVFilterBuffer.free.
- * @param fb buffer to free. fb->priv must be a pointer to the FrameBuffer
- * containing the buffer data.
- */
-void filter_release_buffer(AVFilterBuffer *fb);
-
-/**
- * Free all the buffers in the pool. This must be called after all the
- * buffers have been released.
- */
-void free_buffer_pool(FrameBuffer **pool);
-
#define GET_PIX_FMT_NAME(pix_fmt)\
const char *name = av_get_pix_fmt_name(pix_fmt);
diff --git a/ffmpeg.c b/ffmpeg.c
index 7b6123a6b8..769e9a118b 100644
--- a/ffmpeg.c
+++ b/ffmpeg.c
@@ -478,9 +478,9 @@ static void exit_program(void)
av_freep(&input_files[i]);
}
for (i = 0; i < nb_input_streams; i++) {
- avcodec_free_frame(&input_streams[i]->decoded_frame);
+ av_frame_free(&input_streams[i]->decoded_frame);
+ av_frame_free(&input_streams[i]->filter_frame);
av_dict_free(&input_streams[i]->opts);
- free_buffer_pool(&input_streams[i]->buffer_pool);
avsubtitle_free(&input_streams[i]->prev_sub.subtitle);
avcodec_free_frame(&input_streams[i]->sub2video.frame);
av_freep(&input_streams[i]->filters);
@@ -593,7 +593,10 @@ static void write_frame(AVFormatContext *s, AVPacket *pkt, OutputStream *ost)
}
if (a > 0) {
av_free_packet(pkt);
- new_pkt.destruct = av_destruct_packet;
+ new_pkt.buf = av_buffer_create(new_pkt.data, new_pkt.size,
+ av_buffer_default_free, NULL, 0);
+ if (!new_pkt.buf)
+ exit(1);
} else if (a < 0) {
av_log(NULL, AV_LOG_ERROR, "Failed to open bitstream filter %s for stream %d with codec %s",
bsfc->filter->name, pkt->stream_index,
@@ -909,36 +912,28 @@ static void do_video_out(AVFormatContext *s,
write_frame(s, &pkt, ost);
} else {
int got_packet, forced_keyframe = 0;
- AVFrame big_picture;
double pts_time;
- big_picture = *in_picture;
- /* better than nothing: use input picture interlaced
- settings */
- big_picture.interlaced_frame = in_picture->interlaced_frame;
- if (ost->st->codec->flags & (CODEC_FLAG_INTERLACED_DCT|CODEC_FLAG_INTERLACED_ME)) {
- if (ost->top_field_first == -1)
- big_picture.top_field_first = in_picture->top_field_first;
- else
- big_picture.top_field_first = !!ost->top_field_first;
- }
+ if (ost->st->codec->flags & (CODEC_FLAG_INTERLACED_DCT|CODEC_FLAG_INTERLACED_ME) &&
+ ost->top_field_first >= 0)
+ in_picture->top_field_first = !!ost->top_field_first;
- if (big_picture.interlaced_frame) {
+ if (in_picture->interlaced_frame) {
if (enc->codec->id == AV_CODEC_ID_MJPEG)
- enc->field_order = big_picture.top_field_first ? AV_FIELD_TT:AV_FIELD_BB;
+ enc->field_order = in_picture->top_field_first ? AV_FIELD_TT:AV_FIELD_BB;
else
- enc->field_order = big_picture.top_field_first ? AV_FIELD_TB:AV_FIELD_BT;
+ enc->field_order = in_picture->top_field_first ? AV_FIELD_TB:AV_FIELD_BT;
} else
enc->field_order = AV_FIELD_PROGRESSIVE;
- big_picture.quality = ost->st->codec->global_quality;
+ in_picture->quality = ost->st->codec->global_quality;
if (!enc->me_threshold)
- big_picture.pict_type = 0;
+ in_picture->pict_type = 0;
- pts_time = big_picture.pts != AV_NOPTS_VALUE ?
- big_picture.pts * av_q2d(enc->time_base) : NAN;
+ pts_time = in_picture->pts != AV_NOPTS_VALUE ?
+ in_picture->pts * av_q2d(enc->time_base) : NAN;
if (ost->forced_kf_index < ost->forced_kf_count &&
- big_picture.pts >= ost->forced_kf_pts[ost->forced_kf_index]) {
+ in_picture->pts >= ost->forced_kf_pts[ost->forced_kf_index]) {
ost->forced_kf_index++;
forced_keyframe = 1;
} else if (ost->forced_keyframes_pexpr) {
@@ -965,12 +960,12 @@ static void do_video_out(AVFormatContext *s,
ost->forced_keyframes_expr_const_values[FKF_N] += 1;
}
if (forced_keyframe) {
- big_picture.pict_type = AV_PICTURE_TYPE_I;
+ in_picture->pict_type = AV_PICTURE_TYPE_I;
av_log(NULL, AV_LOG_DEBUG, "Forced keyframe at time %f\n", pts_time);
}
update_benchmark(NULL);
- ret = avcodec_encode_video2(enc, &pkt, &big_picture, &got_packet);
+ ret = avcodec_encode_video2(enc, &pkt, in_picture, &got_packet);
update_benchmark("encode_video %d.%d", ost->file_index, ost->index);
if (ret < 0) {
av_log(NULL, AV_LOG_FATAL, "Video encoding failed\n");
@@ -1066,7 +1061,6 @@ static void do_video_stats(OutputStream *ost, int frame_size)
*/
static int reap_filters(void)
{
- AVFilterBufferRef *picref;
AVFrame *filtered_frame = NULL;
int i;
int64_t frame_pts;
@@ -1087,7 +1081,7 @@ static int reap_filters(void)
filtered_frame = ost->filtered_frame;
while (1) {
- ret = av_buffersink_get_buffer_ref(ost->filter->filter, &picref,
+ ret = av_buffersink_get_frame_flags(ost->filter->filter, filtered_frame,
AV_BUFFERSINK_FLAG_NO_REQUEST);
if (ret < 0) {
if (ret != AVERROR(EAGAIN) && ret != AVERROR_EOF) {
@@ -1099,8 +1093,8 @@ static int reap_filters(void)
break;
}
frame_pts = AV_NOPTS_VALUE;
- if (picref->pts != AV_NOPTS_VALUE) {
- filtered_frame->pts = frame_pts = av_rescale_q(picref->pts,
+ if (filtered_frame->pts != AV_NOPTS_VALUE) {
+ filtered_frame->pts = frame_pts = av_rescale_q(filtered_frame->pts,
ost->filter->filter->inputs[0]->time_base,
ost->st->codec->time_base) -
av_rescale_q(of->start_time,
@@ -1108,7 +1102,7 @@ static int reap_filters(void)
ost->st->codec->time_base);
if (of->start_time && filtered_frame->pts < 0) {
- avfilter_unref_buffer(picref);
+ av_frame_unref(filtered_frame);
continue;
}
}
@@ -1118,15 +1112,13 @@ static int reap_filters(void)
switch (ost->filter->filter->inputs[0]->type) {
case AVMEDIA_TYPE_VIDEO:
- avfilter_copy_buf_props(filtered_frame, picref);
filtered_frame->pts = frame_pts;
if (!ost->frame_aspect_ratio)
- ost->st->codec->sample_aspect_ratio = picref->video->sample_aspect_ratio;
+ ost->st->codec->sample_aspect_ratio = filtered_frame->sample_aspect_ratio;
do_video_out(of->ctx, ost, filtered_frame);
break;
case AVMEDIA_TYPE_AUDIO:
- avfilter_copy_buf_props(filtered_frame, picref);
filtered_frame->pts = frame_pts;
if (!(ost->st->codec->codec->capabilities & CODEC_CAP_PARAM_CHANGE) &&
ost->st->codec->channels != av_frame_get_channels(filtered_frame)) {
@@ -1141,7 +1133,7 @@ static int reap_filters(void)
av_assert0(0);
}
- avfilter_unref_buffer(picref);
+ av_frame_unref(filtered_frame);
}
}
@@ -1482,8 +1474,11 @@ static void do_streamcopy(InputStream *ist, OutputStream *ost, const AVPacket *p
&& ost->st->codec->codec_id != AV_CODEC_ID_MPEG2VIDEO
&& ost->st->codec->codec_id != AV_CODEC_ID_VC1
) {
- if (av_parser_change(ist->st->parser, ost->st->codec, &opkt.data, &opkt.size, pkt->data, pkt->size, pkt->flags & AV_PKT_FLAG_KEY))
- opkt.destruct = av_destruct_packet;
+ if (av_parser_change(ist->st->parser, ost->st->codec, &opkt.data, &opkt.size, pkt->data, pkt->size, pkt->flags & AV_PKT_FLAG_KEY)) {
+ opkt.buf = av_buffer_create(opkt.data, opkt.size, av_buffer_default_free, NULL, 0);
+ if (!opkt.buf)
+ exit(1);
+ }
} else {
opkt.data = pkt->data;
opkt.size = pkt->size;
@@ -1533,13 +1528,15 @@ int guess_input_channel_layout(InputStream *ist)
static int decode_audio(InputStream *ist, AVPacket *pkt, int *got_output)
{
- AVFrame *decoded_frame;
+ AVFrame *decoded_frame, *f;
AVCodecContext *avctx = ist->st->codec;
- int i, ret, resample_changed;
+ int i, ret, err = 0, resample_changed;
AVRational decoded_frame_tb;
if (!ist->decoded_frame && !(ist->decoded_frame = avcodec_alloc_frame()))
return AVERROR(ENOMEM);
+ if (!ist->filter_frame && !(ist->filter_frame = av_frame_alloc()))
+ return AVERROR(ENOMEM);
decoded_frame = ist->decoded_frame;
update_benchmark(NULL);
@@ -1554,7 +1551,11 @@ static int decode_audio(InputStream *ist, AVPacket *pkt, int *got_output)
if (!*got_output || ret < 0) {
if (!pkt->size) {
for (i = 0; i < ist->nb_filters; i++)
+#if 1
av_buffersrc_add_ref(ist->filters[i]->filter, NULL, 0);
+#else
+ av_buffersrc_add_frame(ist->filters[i]->filter, NULL);
+#endif
}
return ret;
}
@@ -1642,25 +1643,37 @@ static int decode_audio(InputStream *ist, AVPacket *pkt, int *got_output)
decoded_frame->pts = av_rescale_delta(decoded_frame_tb, decoded_frame->pts,
(AVRational){1, ist->st->codec->sample_rate}, decoded_frame->nb_samples, &ist->filter_in_rescale_delta_last,
(AVRational){1, ist->st->codec->sample_rate});
- for (i = 0; i < ist->nb_filters; i++)
- av_buffersrc_add_frame_flags(ist->filters[i]->filter, decoded_frame,
- AV_BUFFERSRC_FLAG_KEEP_REF |
+ for (i = 0; i < ist->nb_filters; i++) {
+ if (i < ist->nb_filters - 1) {
+ f = ist->filter_frame;
+ err = av_frame_ref(f, decoded_frame);
+ if (err < 0)
+ break;
+ } else
+ f = decoded_frame;
+ err = av_buffersrc_add_frame_flags(ist->filters[i]->filter, f,
AV_BUFFERSRC_FLAG_PUSH);
-
+ if (err < 0)
+ break;
+ }
decoded_frame->pts = AV_NOPTS_VALUE;
- return ret;
+ av_frame_unref(ist->filter_frame);
+ av_frame_unref(decoded_frame);
+ return err < 0 ? err : ret;
}
static int decode_video(InputStream *ist, AVPacket *pkt, int *got_output)
{
- AVFrame *decoded_frame;
+ AVFrame *decoded_frame, *f;
void *buffer_to_free = NULL;
- int i, ret = 0, resample_changed;
+ int i, ret = 0, err = 0, resample_changed;
int64_t best_effort_timestamp;
AVRational *frame_sample_aspect;
- if (!ist->decoded_frame && !(ist->decoded_frame = avcodec_alloc_frame()))
+ if (!ist->decoded_frame && !(ist->decoded_frame = av_frame_alloc()))
+ return AVERROR(ENOMEM);
+ if (!ist->filter_frame && !(ist->filter_frame = av_frame_alloc()))
return AVERROR(ENOMEM);
decoded_frame = ist->decoded_frame;
pkt->dts = av_rescale_q(ist->dts, AV_TIME_BASE_Q, ist->st->time_base);
@@ -1672,7 +1685,11 @@ static int decode_video(InputStream *ist, AVPacket *pkt, int *got_output)
if (!*got_output || ret < 0) {
if (!pkt->size) {
for (i = 0; i < ist->nb_filters; i++)
+#if 1
av_buffersrc_add_ref(ist->filters[i]->filter, NULL, 0);
+#else
+ av_buffersrc_add_frame(ist->filters[i]->filter, NULL);
+#endif
}
return ret;
}
@@ -1735,27 +1752,15 @@ static int decode_video(InputStream *ist, AVPacket *pkt, int *got_output)
if (!frame_sample_aspect->num)
*frame_sample_aspect = ist->st->sample_aspect_ratio;
- if (ist->dr1 && decoded_frame->type==FF_BUFFER_TYPE_USER && !changed) {
- FrameBuffer *buf = decoded_frame->opaque;
- AVFilterBufferRef *fb = avfilter_get_video_buffer_ref_from_arrays(
- decoded_frame->data, decoded_frame->linesize,
- AV_PERM_READ | AV_PERM_PRESERVE,
- ist->st->codec->width, ist->st->codec->height,
- ist->st->codec->pix_fmt);
-
- avfilter_copy_frame_props(fb, decoded_frame);
- fb->buf->priv = buf;
- fb->buf->free = filter_release_buffer;
-
- av_assert0(buf->refcount>0);
- buf->refcount++;
- av_buffersrc_add_ref(ist->filters[i]->filter, fb,
- AV_BUFFERSRC_FLAG_NO_CHECK_FORMAT |
- AV_BUFFERSRC_FLAG_NO_COPY |
- AV_BUFFERSRC_FLAG_PUSH);
+
+ if (i < ist->nb_filters - 1) {
+ f = ist->filter_frame;
+ err = av_frame_ref(f, decoded_frame);
+ if (err < 0)
+ break;
} else
- if(av_buffersrc_add_frame_flags(ist->filters[i]->filter, decoded_frame,
- AV_BUFFERSRC_FLAG_KEEP_REF |
+ f = decoded_frame;
+ if(av_buffersrc_add_frame_flags(ist->filters[i]->filter, f,
AV_BUFFERSRC_FLAG_PUSH)<0) {
av_log(NULL, AV_LOG_FATAL, "Failed to inject frame into filter network\n");
exit(1);
@@ -1763,8 +1768,10 @@ static int decode_video(InputStream *ist, AVPacket *pkt, int *got_output)
}
+ av_frame_unref(ist->filter_frame);
+ av_frame_unref(decoded_frame);
av_free(buffer_to_free);
- return ret;
+ return err < 0 ? err : ret;
}
static int transcode_subtitles(InputStream *ist, AVPacket *pkt, int *got_output)
@@ -1980,12 +1987,7 @@ static int init_input_stream(int ist_index, char *error, int error_len)
return AVERROR(EINVAL);
}
- ist->dr1 = (codec->capabilities & CODEC_CAP_DR1) && !(FF_API_DEINTERLACE && do_deinterlace);
- if (codec->type == AVMEDIA_TYPE_VIDEO && ist->dr1) {
- ist->st->codec->get_buffer = codec_get_buffer;
- ist->st->codec->release_buffer = codec_release_buffer;
- ist->st->codec->opaque = &ist->buffer_pool;
- }
+ av_opt_set_int(ist->st->codec, "refcounted_frames", 1, 0);
if (!av_dict_get(ist->opts, "threads", NULL, 0))
av_dict_set(&ist->opts, "threads", "auto", 0);
diff --git a/ffmpeg.h b/ffmpeg.h
index 95c2aa6db4..f7178ff6f5 100644
--- a/ffmpeg.h
+++ b/ffmpeg.h
@@ -216,6 +216,7 @@ typedef struct InputStream {
int decoding_needed; /* true if the packets must be decoded in 'raw_fifo' */
AVCodec *dec;
AVFrame *decoded_frame;
+ AVFrame *filter_frame; /* a ref of decoded_frame, to be sent to filters */
int64_t start; /* time when read started */
/* predicted dts of the next packet read for this stream or (when there are
@@ -261,8 +262,6 @@ typedef struct InputStream {
int w, h;
} sub2video;
- /* a pool of free buffers for decoded data */
- FrameBuffer *buffer_pool;
int dr1;
/* decoded data from this stream goes into all those filters
diff --git a/ffplay.c b/ffplay.c
index 7276c4a6e4..c31451a42b 100644
--- a/ffplay.c
+++ b/ffplay.c
@@ -121,14 +121,11 @@ typedef struct VideoPicture {
int64_t pos; // byte position in file
SDL_Overlay *bmp;
int width, height; /* source height & width */
- AVRational sample_aspect_ratio;
int allocated;
int reallocate;
int serial;
-#if CONFIG_AVFILTER
- AVFilterBufferRef *picref;
-#endif
+ AVRational sar;
} VideoPicture;
typedef struct SubPicture {
@@ -256,8 +253,6 @@ typedef struct VideoState {
#if CONFIG_AVFILTER
AVFilterContext *in_video_filter; // the first filter in the video chain
AVFilterContext *out_video_filter; // the last filter in the video chain
- int use_dr1;
- FrameBuffer *buffer_pool;
#endif
int last_video_stream, last_audio_stream, last_subtitle_stream;
@@ -753,10 +748,10 @@ static void calculate_display_rect(SDL_Rect *rect, int scr_xleft, int scr_ytop,
float aspect_ratio;
int width, height, x, y;
- if (vp->sample_aspect_ratio.num == 0)
+ if (vp->sar.num == 0)
aspect_ratio = 0;
else
- aspect_ratio = av_q2d(vp->sample_aspect_ratio);
+ aspect_ratio = av_q2d(vp->sar);
if (aspect_ratio <= 0.0)
aspect_ratio = 1.0;
@@ -982,9 +977,6 @@ static void stream_close(VideoState *is)
/* free all pictures */
for (i = 0; i < VIDEO_PICTURE_QUEUE_SIZE; i++) {
vp = &is->pictq[i];
-#if CONFIG_AVFILTER
- avfilter_unref_bufferp(&vp->picref);
-#endif
if (vp->bmp) {
SDL_FreeYUVOverlay(vp->bmp);
vp->bmp = NULL;
@@ -1477,10 +1469,6 @@ static void alloc_picture(VideoState *is)
if (vp->bmp)
SDL_FreeYUVOverlay(vp->bmp);
-#if CONFIG_AVFILTER
- avfilter_unref_bufferp(&vp->picref);
-#endif
-
video_open(is, 0, vp);
vp->bmp = SDL_CreateYUVOverlay(vp->width, vp->height,
@@ -1544,9 +1532,9 @@ static int queue_picture(VideoState *is, AVFrame *src_frame, double pts, int64_t
vp = &is->pictq[is->pictq_windex];
#if CONFIG_AVFILTER
- vp->sample_aspect_ratio = ((AVFilterBufferRef *)src_frame->opaque)->video->sample_aspect_ratio;
+ vp->sar = src_frame->sample_aspect_ratio;
#else
- vp->sample_aspect_ratio = av_guess_sample_aspect_ratio(is->ic, is->video_st, src_frame);
+ vp->sar = av_guess_sample_aspect_ratio(is->ic, is->video_st, src_frame);
#endif
/* alloc or resize hardware picture buffer */
@@ -1586,10 +1574,6 @@ static int queue_picture(VideoState *is, AVFrame *src_frame, double pts, int64_t
/* if the frame is not skipped, then display it */
if (vp->bmp) {
AVPicture pict = { { 0 } };
-#if CONFIG_AVFILTER
- avfilter_unref_bufferp(&vp->picref);
- vp->picref = src_frame->opaque;
-#endif
/* get a pointer on the bitmap */
SDL_LockYUVOverlay (vp->bmp);
@@ -1658,7 +1642,6 @@ static int get_video_frame(VideoState *is, AVFrame *frame, int64_t *pts, AVPacke
is->frame_timer = (double)av_gettime() / 1000000.0;
is->frame_last_dropped_pts = AV_NOPTS_VALUE;
SDL_UnlockMutex(is->pictq_mutex);
-
return 0;
}
@@ -1804,7 +1787,7 @@ static int video_thread(void *arg)
{
AVPacket pkt = { 0 };
VideoState *is = arg;
- AVFrame *frame = avcodec_alloc_frame();
+ AVFrame *frame = av_frame_alloc();
int64_t pts_int = AV_NOPTS_VALUE, pos = -1;
double pts;
int ret;
@@ -1818,18 +1801,10 @@ static int video_thread(void *arg)
int last_h = 0;
enum AVPixelFormat last_format = -2;
int last_serial = -1;
-
- if (codec->codec->capabilities & CODEC_CAP_DR1) {
- is->use_dr1 = 1;
- codec->get_buffer = codec_get_buffer;
- codec->release_buffer = codec_release_buffer;
- codec->opaque = &is->buffer_pool;
- }
#endif
for (;;) {
#if CONFIG_AVFILTER
- AVFilterBufferRef *picref;
AVRational tb;
#endif
while (is->paused && !is->videoq.abort_request)
@@ -1876,30 +1851,17 @@ static int video_thread(void *arg)
frame->pts = pts_int;
frame->sample_aspect_ratio = av_guess_sample_aspect_ratio(is->ic, is->video_st, frame);
- if (is->use_dr1 && frame->opaque) {
- FrameBuffer *buf = frame->opaque;
- AVFilterBufferRef *fb = avfilter_get_video_buffer_ref_from_arrays(
- frame->data, frame->linesize,
- AV_PERM_READ | AV_PERM_PRESERVE,
- frame->width, frame->height,
- frame->format);
-
- avfilter_copy_frame_props(fb, frame);
- fb->buf->priv = buf;
- fb->buf->free = filter_release_buffer;
-
- buf->refcount++;
- av_buffersrc_add_ref(filt_in, fb, AV_BUFFERSRC_FLAG_NO_COPY);
-
- } else
- av_buffersrc_write_frame(filt_in, frame);
-
+ ret = av_buffersrc_add_frame(filt_in, frame);
+ if (ret < 0)
+ goto the_end;
+ av_frame_unref(frame);
+ avcodec_get_frame_defaults(frame);
av_free_packet(&pkt);
while (ret >= 0) {
is->frame_last_returned_time = av_gettime() / 1000000.0;
- ret = av_buffersink_get_buffer_ref(filt_out, &picref, 0);
+ ret = av_buffersink_get_frame_flags(filt_out, frame, 0);
if (ret < 0) {
ret = 0;
break;
@@ -1909,13 +1871,9 @@ static int video_thread(void *arg)
if (fabs(is->frame_last_filter_delay) > AV_NOSYNC_THRESHOLD / 10.0)
is->frame_last_filter_delay = 0;
- avfilter_copy_buf_props(frame, picref);
-
- pts_int = picref->pts;
+ pts_int = frame->pts;
tb = filt_out->inputs[0]->time_base;
- pos = picref->pos;
- frame->opaque = picref;
-
+ pos = av_frame_get_pkt_pos(frame);
if (av_cmp_q(tb, is->video_st->time_base)) {
av_unused int64_t pts1 = pts_int;
pts_int = av_rescale_q(pts_int, tb, is->video_st->time_base);
@@ -1926,10 +1884,12 @@ static int video_thread(void *arg)
}
pts = pts_int * av_q2d(is->video_st->time_base);
ret = queue_picture(is, frame, pts, pos, serial);
+ av_frame_unref(frame);
}
#else
pts = pts_int * av_q2d(is->video_st->time_base);
ret = queue_picture(is, frame, pts, pkt.pos, serial);
+ av_frame_unref(frame);
#endif
if (ret < 0)
@@ -1941,7 +1901,7 @@ static int video_thread(void *arg)
avfilter_graph_free(&graph);
#endif
av_free_packet(&pkt);
- avcodec_free_frame(&frame);
+ av_frame_free(&frame);
return 0;
}
@@ -2384,6 +2344,8 @@ static int stream_component_open(VideoState *is, int stream_index)
opts = filter_codec_opts(codec_opts, avctx->codec_id, ic, ic->streams[stream_index], codec);
if (!av_dict_get(opts, "threads", NULL, 0))
av_dict_set(&opts, "threads", "auto", 0);
+ if (avctx->codec_type == AVMEDIA_TYPE_VIDEO)
+ av_dict_set(&opts, "refcounted_frames", "1", 0);
if (avcodec_open2(avctx, codec, &opts) < 0)
return -1;
if ((t = av_dict_get(opts, "", NULL, AV_DICT_IGNORE_SUFFIX))) {
@@ -2504,9 +2466,6 @@ static void stream_component_close(VideoState *is, int stream_index)
ic->streams[stream_index]->discard = AVDISCARD_ALL;
avcodec_close(avctx);
-#if CONFIG_AVFILTER
- free_buffer_pool(&is->buffer_pool);
-#endif
switch (avctx->codec_type) {
case AVMEDIA_TYPE_AUDIO:
is->audio_st = NULL;