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