diff options
author | Michael Niedermayer <michaelni@gmx.at> | 2013-03-12 16:40:42 +0400 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2013-03-12 17:16:02 +0400 |
commit | 32fdfdfbdac64c57b12910521af1379a24d01f73 (patch) | |
tree | 865ec201a41ac45d0ce0c58b3d7ea9a438d20d08 /ffmpeg.c | |
parent | 3c1326411d6ffd2f30c0d6e8cc32d34b5ed5a518 (diff) | |
parent | 354468fc12dcf93e7fb4af552e18906771913273 (diff) |
Merge commit '354468fc12dcf93e7fb4af552e18906771913273'
* commit '354468fc12dcf93e7fb4af552e18906771913273':
avplay: switch to new refcounted frames API
avconv: convert to new refcounted AVFrame API
Conflicts:
cmdutils.c
ffmpeg.c
ffmpeg.h
ffplay.c
Merged-by: Michael Niedermayer <michaelni@gmx.at>
Diffstat (limited to 'ffmpeg.c')
-rw-r--r-- | ffmpeg.c | 146 |
1 files changed, 74 insertions, 72 deletions
@@ -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); |