diff options
author | Michael Niedermayer <michaelni@gmx.at> | 2013-11-23 14:26:27 +0100 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2013-11-23 14:31:15 +0100 |
commit | 62e10c375968d9cbbe2a0bc321e00eef52d32917 (patch) | |
tree | 8c8a3a4b025d3cf54abb44a3ab988c58c2c9e615 /ffmpeg.c | |
parent | 94194bdcd7bfc2137ccd13e5c149567b9a917f4f (diff) | |
parent | 07fd0a22192805d56c635eb294dc26b0a54ae325 (diff) | |
download | ffmpeg-62e10c375968d9cbbe2a0bc321e00eef52d32917.tar.gz |
Merge commit '07fd0a22192805d56c635eb294dc26b0a54ae325'
* commit '07fd0a22192805d56c635eb294dc26b0a54ae325':
avconv: add infrastructure for using hwaccels
Conflicts:
ffmpeg.c
ffmpeg.h
ffmpeg_filter.c
ffmpeg_opt.c
Merged-by: Michael Niedermayer <michaelni@gmx.at>
Diffstat (limited to 'ffmpeg.c')
-rw-r--r-- | ffmpeg.c | 73 |
1 files changed, 73 insertions, 0 deletions
@@ -489,6 +489,7 @@ static void ffmpeg_cleanup(int ret) avsubtitle_free(&input_streams[i]->prev_sub.subtitle); av_frame_free(&input_streams[i]->sub2video.frame); av_freep(&input_streams[i]->filters); + av_freep(&input_streams[i]->hwaccel_device); av_freep(&input_streams[i]); } @@ -1707,6 +1708,13 @@ static int decode_video(InputStream *ist, AVPacket *pkt, int *got_output) if(ist->top_field_first>=0) decoded_frame->top_field_first = ist->top_field_first; + if (ist->hwaccel_retrieve_data && decoded_frame->format == ist->hwaccel_pix_fmt) { + err = ist->hwaccel_retrieve_data(ist->st->codec, decoded_frame); + if (err < 0) + goto fail; + } + ist->hwaccel_retrieved_pix_fmt = decoded_frame->format; + best_effort_timestamp= av_frame_get_best_effort_timestamp(decoded_frame); if(best_effort_timestamp != AV_NOPTS_VALUE) ist->next_pts = ist->pts = av_rescale_q(decoded_frame->pts = best_effort_timestamp, ist->st->time_base, AV_TIME_BASE_Q); @@ -1771,6 +1779,7 @@ static int decode_video(InputStream *ist, AVPacket *pkt, int *got_output) } } +fail: av_frame_unref(ist->filter_frame); av_frame_unref(decoded_frame); return err < 0 ? err : ret; @@ -1982,6 +1991,63 @@ static void print_sdp(void) av_freep(&avc); } +static const HWAccel *get_hwaccel(enum AVPixelFormat pix_fmt) +{ + int i; + for (i = 0; hwaccels[i].name; i++) + if (hwaccels[i].pix_fmt == pix_fmt) + return &hwaccels[i]; + return NULL; +} + +static enum AVPixelFormat get_format(AVCodecContext *s, const enum AVPixelFormat *pix_fmts) +{ + InputStream *ist = s->opaque; + const enum AVPixelFormat *p; + int ret; + + for (p = pix_fmts; *p != -1; p++) { + const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(*p); + const HWAccel *hwaccel; + + if (!(desc->flags & AV_PIX_FMT_FLAG_HWACCEL)) + break; + + hwaccel = get_hwaccel(*p); + if (!hwaccel || + (ist->active_hwaccel_id && ist->active_hwaccel_id != hwaccel->id) || + (ist->hwaccel_id != HWACCEL_AUTO && ist->hwaccel_id != hwaccel->id)) + continue; + + ret = hwaccel->init(s); + if (ret < 0) { + if (ist->hwaccel_id == hwaccel->id) { + av_log(NULL, AV_LOG_FATAL, + "%s hwaccel requested for input stream #%d:%d, " + "but cannot be initialized.\n", hwaccel->name, + ist->file_index, ist->st->index); + exit_program(1); + } + continue; + } + ist->active_hwaccel_id = hwaccel->id; + ist->hwaccel_pix_fmt = *p; + break; + } + + return *p; +} + +static int get_buffer(AVCodecContext *s, AVFrame *frame, int flags) +{ + InputStream *ist = s->opaque; + + if (ist->hwaccel_get_buffer && frame->format == ist->hwaccel_pix_fmt) + return ist->hwaccel_get_buffer(s, frame, flags); + + return avcodec_default_get_buffer2(s, frame, flags); +} + static int init_input_stream(int ist_index, char *error, int error_len) { int ret; @@ -1995,6 +2061,11 @@ static int init_input_stream(int ist_index, char *error, int error_len) return AVERROR(EINVAL); } + ist->st->codec->opaque = ist; + ist->st->codec->get_format = get_format; + ist->st->codec->get_buffer2 = get_buffer; + ist->st->codec->thread_safe_callbacks = 1; + av_opt_set_int(ist->st->codec, "refcounted_frames", 1, 0); if (!av_dict_get(ist->opts, "threads", NULL, 0)) @@ -3326,6 +3397,8 @@ static int transcode(void) ist = input_streams[i]; if (ist->decoding_needed) { avcodec_close(ist->st->codec); + if (ist->hwaccel_uninit) + ist->hwaccel_uninit(ist->st->codec); } } |