[FFmpeg-user] The transcoded file can't see the video played by the JW player which used the VAAPI to transcode file to the FLV format.

Mark Thompson sw at jkqxz.net
Mon Dec 5 23:11:19 EET 2016


On 05/12/16 17:37, Archer Chang wrote:
> 2016-12-05 23:52 GMT+08:00 Mark Thompson <sw at jkqxz.net>:
>> On 05/12/16 12:51, Archer Chang wrote:
>>> I use the VAAPI HW ACCEL to transcode file to the FLV format that the
>>> command as follows.
>>>
>>> ffmpeg -vaapi_device /dev/dri/renderD128 -hwaccel vaapi
>>> -hwaccel_output_format vaapi -hwaccel_lax_profile_check -i infile.mkv
>> -vf
>>> "format=nv12|vaapi,hwupload" -c:v h264_vaapi -c:a aac -ac 2 -ar 44100
>>> *outfile1.flv*
>>>
>>> The transcoded file(outfile.flv) only can hear the audio but no video
>> that
>>> played by the JW player.  But when I transcode the file to the MKV and
>> make
>>> the stream copy to the FLV format and
>>> this file can be played normally by the JW player. The command as
>> follows.
>>>
>>> ffmpeg -vaapi_device /dev/dri/renderD128 -hwaccel vaapi
>>> -hwaccel_output_format vaapi -hwaccel_lax_profile_check -i infile.mkv
>> -vf
>>> "format=nv12|vaapi,hwupload" -c:v h264_vaapi -c:a aac -ac 2 -ar 44100
>>>  outfile.mkv
>>> ffmpeg -i outfile.mkv  -c:v copy -c:a copy  *outfile2.flv*
>>>
>>> I try to use the flv parser utility to find out the difference between
>> the
>>> outfile1.flv and the outfile2.flv.
>>> Seems the Video Tag1 were different. the content as follows.
>>>
>>> outfile1.flv (transcode using the ffmpeg directly with VAAPI)
>>> 09 00 00 05 00 00 00 00 00 00 00 17 00 00 00 00
>>>
>>> outfile2.flv(mke the stream copy from transcoded file)
>>> 09 00 00 30 00 00 00 00 00 00 00 17 00 00 00 00
>>> 01 6E 00 28 FF E1 00 1A 67 6E 00 28 A6 CD 94 07
>>> 80 22 7E 5C 04 40 00 00 FA 40 00 2E E0 03 C6 0C
>>> 65 80 01 00 06 68 EB E3 CB 22 C0
>>>
>>> I not familiar with the video transcoding. I trace the flvenc.c seems the
>>> par->extradata_size would be 0 when use the VAAPI to transcode the file
>> to
>>> the FLV directly,
>>> And it has some value which makes stream copy or use SW transcode
>>>
>>> ffmpeg  -i infile.mkv   -c:v libx264 -c:a aac -ac 2 -ar 44100
>> *outfile.flv
>>>  (can be played  normally by JW Player)*
>>
>> Is this JW player something which can only play streams with global
>> headers, then?
>>
>> If so, try applying <https://git.libav.org/?p=libav.git;a=commit;h=
>> 0cf86fabfa5820596cca2cfead63c6f8df76c3f2> and see if it works.
>>
>> (This is on the assumption that you are using a packed-header VAAPI driver
>> like i965, if you are using a whole-stream driver like mesa/gallium then it
>> isn't really fixable.)
> 
> Hi Mark,
> 
> It works with the applying <https://git.libav.org/?p=libav.git;a=commit;h=
> 0cf86fabfa5820596cca2cfead63c6f8df76c3f2>
> The JW player seem can only play streams with global headers.
> 
> Thank you very much.
> 
> Thanks again
> Archer Chang


Merged as below.

Thanks,

- Mark


On 05/12/16 21:09, Mark Thompson wrote:
> ffmpeg | branch: master | Mark Thompson <sw at jkqxz.net> | Sun Oct  2 08:48:34 2016 +0100| [51020adcecf4004c1586a708d96acc6cbddd050a] | committer: Mark Thompson
> 
> vaapi_encode: Write sequence header as extradata
> 
> Only works if packed headers are supported, where we can know the
> output before generating the first frame.
> 
> (cherry picked from commit 0cf86fabfa5820596cca2cfead63c6f8df76c3f2)
> 
>> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=51020adcecf4004c1586a708d96acc6cbddd050a
> ---
> 
>  libavcodec/vaapi_encode.c | 22 ++++++++++++++++++++++
>  libavcodec/vaapi_encode.h |  2 ++
>  2 files changed, 24 insertions(+)
> 
> diff --git a/libavcodec/vaapi_encode.c b/libavcodec/vaapi_encode.c
> index 262968a..a3c9991 100644
> --- a/libavcodec/vaapi_encode.c
> +++ b/libavcodec/vaapi_encode.c
> @@ -1405,6 +1405,28 @@ av_cold int ff_vaapi_encode_init(AVCodecContext *avctx)
>      // where it actually overlaps properly, though.)
>      ctx->issue_mode = ISSUE_MODE_MAXIMISE_THROUGHPUT;
>  
> +    if (ctx->va_packed_headers & VA_ENC_PACKED_HEADER_SEQUENCE &&
> +        ctx->codec->write_sequence_header) {
> +        char data[MAX_PARAM_BUFFER_SIZE];
> +        size_t bit_len = 8 * sizeof(data);
> +
> +        err = ctx->codec->write_sequence_header(avctx, data, &bit_len);
> +        if (err < 0) {
> +            av_log(avctx, AV_LOG_ERROR, "Failed to write sequence header "
> +                   "for extradata: %d.\n", err);
> +            goto fail;
> +        } else {
> +            avctx->extradata_size = (bit_len + 7) / 8;
> +            avctx->extradata = av_mallocz(avctx->extradata_size +
> +                                          AV_INPUT_BUFFER_PADDING_SIZE);
> +            if (!avctx->extradata) {
> +                err = AVERROR(ENOMEM);
> +                goto fail;
> +            }
> +            memcpy(avctx->extradata, data, avctx->extradata_size);
> +        }
> +    }
> +
>      return 0;
>  
>  fail:
> diff --git a/libavcodec/vaapi_encode.h b/libavcodec/vaapi_encode.h
> index abce6b8..cc05ac8 100644
> --- a/libavcodec/vaapi_encode.h
> +++ b/libavcodec/vaapi_encode.h
> @@ -235,6 +235,8 @@ typedef struct VAAPIEncodeType {
>      int slice_header_type;
>  
>      // Write the packed header data to the provided buffer.
> +    // The sequence header is also used to fill the codec extradata
> +    // when the encoder is starting.
>      int (*write_sequence_header)(AVCodecContext *avctx,
>                                   char *data, size_t *data_len);
>      int  (*write_picture_header)(AVCodecContext *avctx,


More information about the ffmpeg-user mailing list