[FFmpeg-devel,6/6] ffmpeg: Pass the global device context to encoder and decoder instances

Submitted by Mark Thompson on Jan. 17, 2017, 10:32 p.m.

Details

Message ID eea6c027-29a5-090f-8847-1e1d512f5dc2@jkqxz.net
State New
Headers show

Commit Message

Mark Thompson Jan. 17, 2017, 10:32 p.m.
---
 ffmpeg.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)

Comments

wm4 Jan. 18, 2017, 8:03 a.m.
On Tue, 17 Jan 2017 22:32:15 +0000
Mark Thompson <sw@jkqxz.net> wrote:

> ---
>  ffmpeg.c | 12 ++++++++++++
>  1 file changed, 12 insertions(+)
> 
> diff --git a/ffmpeg.c b/ffmpeg.c
> index 6d1e358..781c0a4 100644
> --- a/ffmpeg.c
> +++ b/ffmpeg.c
> @@ -2748,6 +2748,12 @@ static int init_input_stream(int ist_index, char *error, int error_len)
>           * audio, and video decoders such as cuvid or mediacodec */
>          av_codec_set_pkt_timebase(ist->dec_ctx, ist->st->time_base);
>  
> +        if (hw_device_ctx) {
> +            ist->dec_ctx->hw_device_ctx = av_buffer_ref(hw_device_ctx);
> +            if (!ist->dec_ctx->hw_device_ctx)
> +                return AVERROR(ENOMEM);
> +        }
> +
>          if (!av_dict_get(ist->decoder_opts, "threads", NULL, 0))
>              av_dict_set(&ist->decoder_opts, "threads", "auto", 0);
>          if ((ret = avcodec_open2(ist->dec_ctx, codec, &ist->decoder_opts)) < 0) {
> @@ -3271,6 +3277,12 @@ static int init_output_stream(OutputStream *ost, char *error, int error_len)
>              !av_dict_get(ost->encoder_opts, "ab", NULL, 0))
>              av_dict_set(&ost->encoder_opts, "b", "128000", 0);
>  
> +        if (hw_device_ctx) {
> +            ost->enc_ctx->hw_device_ctx = av_buffer_ref(hw_device_ctx);
> +            if (!ost->enc_ctx->hw_device_ctx)
> +                return AVERROR(ENOMEM);
> +        }
> +
>          if (ost->filter && av_buffersink_get_hw_frames_ctx(ost->filter->filter)) {
>              ost->enc_ctx->hw_frames_ctx = av_buffer_ref(av_buffersink_get_hw_frames_ctx(ost->filter->filter));
>              if (!ost->enc_ctx->hw_frames_ctx)

Doesn't this break the case when hw decoder and encoder are different?
Mark Thompson Jan. 21, 2017, 10:27 p.m.
On 18/01/17 08:03, wm4 wrote:
> On Tue, 17 Jan 2017 22:32:15 +0000
> Mark Thompson <sw@jkqxz.net> wrote:
> 
>> ---
>>  ffmpeg.c | 12 ++++++++++++
>>  1 file changed, 12 insertions(+)
>>
>> diff --git a/ffmpeg.c b/ffmpeg.c
>> index 6d1e358..781c0a4 100644
>> --- a/ffmpeg.c
>> +++ b/ffmpeg.c
>> @@ -2748,6 +2748,12 @@ static int init_input_stream(int ist_index, char *error, int error_len)
>>           * audio, and video decoders such as cuvid or mediacodec */
>>          av_codec_set_pkt_timebase(ist->dec_ctx, ist->st->time_base);
>>  
>> +        if (hw_device_ctx) {
>> +            ist->dec_ctx->hw_device_ctx = av_buffer_ref(hw_device_ctx);
>> +            if (!ist->dec_ctx->hw_device_ctx)
>> +                return AVERROR(ENOMEM);
>> +        }
>> +
>>          if (!av_dict_get(ist->decoder_opts, "threads", NULL, 0))
>>              av_dict_set(&ist->decoder_opts, "threads", "auto", 0);
>>          if ((ret = avcodec_open2(ist->dec_ctx, codec, &ist->decoder_opts)) < 0) {
>> @@ -3271,6 +3277,12 @@ static int init_output_stream(OutputStream *ost, char *error, int error_len)
>>              !av_dict_get(ost->encoder_opts, "ab", NULL, 0))
>>              av_dict_set(&ost->encoder_opts, "b", "128000", 0);
>>  
>> +        if (hw_device_ctx) {
>> +            ost->enc_ctx->hw_device_ctx = av_buffer_ref(hw_device_ctx);
>> +            if (!ost->enc_ctx->hw_device_ctx)
>> +                return AVERROR(ENOMEM);
>> +        }
>> +
>>          if (ost->filter && av_buffersink_get_hw_frames_ctx(ost->filter->filter)) {
>>              ost->enc_ctx->hw_frames_ctx = av_buffer_ref(av_buffersink_get_hw_frames_ctx(ost->filter->filter));
>>              if (!ost->enc_ctx->hw_frames_ctx)
> 
> Doesn't this break the case when hw decoder and encoder are different?

Yes, but there is only a single global in ffmpeg.c anyway so we would need more magic to make more interesting combinations work?

I'm reconsidering this one anyway in light of the comments in the device thread (hw_device_ctx wants to be unset for the user-supplied hw_frames_ctx case).  I think it only wants to be set for codecs we know want it.

(The qsv code should also check that the device is actually of AV_HWDEVICE_TYPE_QSV to avoid possible madness, I will add that.)

Patch hide | download patch | download mbox

diff --git a/ffmpeg.c b/ffmpeg.c
index 6d1e358..781c0a4 100644
--- a/ffmpeg.c
+++ b/ffmpeg.c
@@ -2748,6 +2748,12 @@  static int init_input_stream(int ist_index, char *error, int error_len)
          * audio, and video decoders such as cuvid or mediacodec */
         av_codec_set_pkt_timebase(ist->dec_ctx, ist->st->time_base);
 
+        if (hw_device_ctx) {
+            ist->dec_ctx->hw_device_ctx = av_buffer_ref(hw_device_ctx);
+            if (!ist->dec_ctx->hw_device_ctx)
+                return AVERROR(ENOMEM);
+        }
+
         if (!av_dict_get(ist->decoder_opts, "threads", NULL, 0))
             av_dict_set(&ist->decoder_opts, "threads", "auto", 0);
         if ((ret = avcodec_open2(ist->dec_ctx, codec, &ist->decoder_opts)) < 0) {
@@ -3271,6 +3277,12 @@  static int init_output_stream(OutputStream *ost, char *error, int error_len)
             !av_dict_get(ost->encoder_opts, "ab", NULL, 0))
             av_dict_set(&ost->encoder_opts, "b", "128000", 0);
 
+        if (hw_device_ctx) {
+            ost->enc_ctx->hw_device_ctx = av_buffer_ref(hw_device_ctx);
+            if (!ost->enc_ctx->hw_device_ctx)
+                return AVERROR(ENOMEM);
+        }
+
         if (ost->filter && av_buffersink_get_hw_frames_ctx(ost->filter->filter)) {
             ost->enc_ctx->hw_frames_ctx = av_buffer_ref(av_buffersink_get_hw_frames_ctx(ost->filter->filter));
             if (!ost->enc_ctx->hw_frames_ctx)