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>
This commit is contained in:
Michael Niedermayer
2013-11-23 14:26:27 +01:00
5 changed files with 179 additions and 2 deletions

View File

@@ -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);
}
}