[FFmpeg-devel] Added HW H.264 and HEVC encoding for AMD GPUs based on AMF SDK

Mironov, Mikhail Mikhail.Mironov at amd.com
Tue Nov 14 18:20:37 EET 2017


> -----Original Message-----
> From: ffmpeg-devel [mailto:ffmpeg-devel-bounces at ffmpeg.org] On Behalf
> Of Mironov, Mikhail
> Sent: November 14, 2017 10:51 AM
> To: FFmpeg development discussions and patches <ffmpeg-
> devel at ffmpeg.org>
> Subject: Re: [FFmpeg-devel] Added HW H.264 and HEVC encoding for AMD
> GPUs based on AMF SDK
> 
> > -----Original Message-----
> > From: ffmpeg-devel [mailto:ffmpeg-devel-bounces at ffmpeg.org] On Behalf
> > Of Mark Thompson
> > Sent: November 14, 2017 9:14 AM
> > To: ffmpeg-devel at ffmpeg.org
> > Subject: Re: [FFmpeg-devel] Added HW H.264 and HEVC encoding for AMD
> > GPUs based on AMF SDK
> >
> > On 13/11/17 23:00, Mironov, Mikhail wrote:
> > >>> +    res = ctx->factory->pVtbl->CreateContext(ctx->factory, &ctx-
> > >context);
> > >>> +    AMF_RETURN_IF_FALSE(ctx, res == AMF_OK, AVERROR_UNKNOWN,
> > >> "CreateContext() failed with error %d\n", res);
> > >>> +    // try to reuse existing DX device
> > >>> +    if (avctx->hw_frames_ctx) {
> > >>> +        AVHWFramesContext *device_ctx =
> > >>> + (AVHWFramesContext*)avctx-
> > >>> hw_frames_ctx->data;
> > >>> +        if (device_ctx->device_ctx->type ==
> > AV_HWDEVICE_TYPE_D3D11VA){
> > >>> +            if (amf_av_to_amf_format(device_ctx->sw_format) ==
> > >>> + AMF_SURFACE_UNKNOWN) {
> > >>
> > >> This test is inverted.
> > >>
> > >> Have you actually tested this path?  Even with that test fixed, I'm
> > >> unable to pass the following initialisation test with an AMD D3D11
> device.
> > >>
> > >
> > > Yes, the condition should be reverted. To test I had to add
> > > "-hwaccel d3d11va -hwaccel_output_format d3d11" to the command
> line.
> >
> > Yeah.  I get:
> >
> > $ ./ffmpeg_g -y -hwaccel d3d11va -hwaccel_device 0 -
> > hwaccel_output_format d3d11 -i ~/bbb_1080_264.mp4 -an -c:v h264_amf
> > out.mp4 ...
> > [AVHWDeviceContext @ 000000000270e120] Created on device 1002:665f
> > (AMD Radeon (TM) R7 360 Series).
> > ...
> > [h264_amf @ 00000000004dcd80] amf_shared: avctx->hw_frames_ctx has
> > non-AMD device, switching to default
> >
> > It's then comedically slow in this state (about 2fps), but works fine
> > when the decode is in software.
> 
> Is it possible that you also have iGPU not disabled and it is used for decoding
> as adapter 0?
> Can you provide a log from dxdiag.exe?
> If AMF created own DX device then submission logic an speed is the same as
> from SW decoder.
> It would be interesting to see a short GPUVIEW log.
> 
> >
> > >>> +
> > >>> +    // Dynamic
> > >>> +    /// Rate Control Method
> > >>> +    { "rc",             "Rate Control Method",
> > >> OFFSET(rate_control_mode),  AV_OPT_TYPE_INT,   { .i64 =
> > >>
> >
> AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_PEAK_CONSTRAINED_VB
> > >> R    },
> AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_CONSTANT_QP,
> > >>
> >
> AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_LATENCY_CONSTRAINED
> > >> _VBR, VE, "rc" },
> > >>> +    { "cqp",            "Constant Quantization Parameter",      0,
> > >> AV_OPT_TYPE_CONST, { .i64 =
> > >> AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_CONSTANT_QP
> > },
> > >> 0, 0, VE, "rc" },
> > >>> +    { "cbr",            "Constant Bitrate",                     0,
> > >> AV_OPT_TYPE_CONST, { .i64 =
> > >> AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_CBR                     }, 0,
> 0,
> > >> VE, "rc" },
> > >>> +    { "vbr_peak",       "Peak Contrained Variable Bitrate",     0,
> > >> AV_OPT_TYPE_CONST, { .i64 =
> > >>
> >
> AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_PEAK_CONSTRAINED_VB
> > >> R    }, 0, 0, VE, "rc" },
> > >>> +    { "vbr_latency",    "Latency Constrained Variable Bitrate", 0,
> > >> AV_OPT_TYPE_CONST, { .i64 =
> > >>
> >
> AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_LATENCY_CONSTRAINED
> > >> _VBR }, 0, 0, VE, "rc" },
> > >>
> > >> I think the default for this option needs to be decided dynamically.
> > >> Just setting "-b:v" is a not-unreasonable thing to do, and
> > >> currently the choice of PEAK_CONSTRAINED_VBR makes it then
> complain
> > >> that
> > maxrate isn't set.
> > >> Similarly, if the only setting is some constant-quality option
> > >> (-q/- global_quality, or your private ones below), it ignores that
> > >> and use the default 2Mbps instead.
> > >>
> > >>> +    /// Enforce HRD, Filler Data, VBAQ, Frame Skipping
> > >>> +    { "enforce_hrd",    "Enforce HRD",
> > OFFSET(enforce_hrd),
> > >> AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE },
> > >>
> > >> Does this option work?  I don't seem to be able to push it into
> > >> generating HRD information with any combination of options.
> > >>
> > >
> > > Fixed.
> >
> > What combination of options are needed to get the HRD parameters in
> > the output stream?  I still don't see them with the new version.
> 
> From codec team: AMF HRD parameter ensures that the output stream is
> conformant to HRD bit rate requirements but does not add SEI any other
> stream parameters.
> 
> >
> > >>> +    { "filler_data",    "Filler Data Enable",                   OFFSET(filler_data),
> > >> AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE },
> > >>> +    { "vbaq",           "Enable VBAQ",                          OFFSET(enable_vbaq),
> > >> AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE },
> > >>> +    { "frame_skipping", "Rate Control Based Frame Skip",
> > >> OFFSET(skip_frame),         AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE },
> > >>> +
> > >>> +    /// QP Values
> > >>> +    { "qp_i",           "Quantization Parameter for I-Frame",
> OFFSET(qp_i),
> > >> AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 51, VE },
> > >>> +    { "qp_p",           "Quantization Parameter for P-Frame",
> > OFFSET(qp_p),
> > >> AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 51, VE },
> > >>> +    { "qp_b",           "Quantization Parameter for B-Frame",
> > OFFSET(qp_b),
> > >> AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 51, VE },
> > >>> +
> > >>> +    /// Pre-Pass, Pre-Analysis, Two-Pass
> > >>> +    { "preanalysis",    "Pre-Analysis Mode",
> > OFFSET(preanalysis),
> > >> AV_OPT_TYPE_BOOL,{ .i64 = 0 }, 0, 1, VE, NULL },
> > >>> +
> > >>> +    /// Maximum Access Unit Size
> > >>> +    { "max_au_size",    "Maximum Access Unit Size for rate control (in
> > bits)",
> > >> OFFSET(max_au_size),        AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX,
> VE
> > },
> > >>
> > >> Can you explain more about what this option does?  I don't seem to
> > >> be able to get it to do anything - e.g. setting -max_au_size 80000
> > >> with 30fps CBR 1M (which should be easily achievable) still makes
> > >> packets of more than 80000
> > >> bits.)
> > >>
> > >
> > > It means maximum frame size in bits, and it should be used together
> > > with enforce_hrd enabled.  I tested, it works after the related fix
> > > for
> > enforce_hrd.
> > > I added  dependency handling.
> >
> > $ ./ffmpeg_g -y -nostats -i ~/bbb_1080_264.mp4 -an -c:v h264_amf
> > -bsf:v trace_headers -frames:v 1000 -enforce_hrd 1 -b:v 1M -maxrate 1M
> > - max_au_size 80000 out.mp4 2>&1 | grep 'Packet: [0-9]\{5\}'
> > [AVBSFContext @ 00000000029d7f40] Packet: 11426 bytes, key frame, pts
> > 128000, dts 128000.
> > [AVBSFContext @ 00000000029d7f40] Packet: 17623 bytes, key frame, pts
> > 192000, dts 192000.
> > [AVBSFContext @ 00000000029d7f40] Packet: 23358 bytes, pts 249856, dts
> > 249856.
> >
> > (That is, packets bigger than the supposed 80000-bit maximum.)  Expected?
> 
> No, this is not expected. I tried the exact command line and did not get
> packages more then 80000 bits. Sorry to ask but did you apply the change in
> amfenc.h?
> 

Sorry, the change is in amfsdkenc.h

> >
> > >>
> > >> And some thoughts on the stream it makes:
> > >>
> > >> "ffmpeg_g -report -y -f lavfi -i testsrc -an -c:v h264_amf -bsf:v
> > >> trace_headers - frames:v 1000 out.mp4"
> > >>
> > >> [AVBSFContext @ 000000000049b9c0] Sequence Parameter Set
> > >> [AVBSFContext @ 000000000049b9c0] 40          max_num_ref_frames
> > >> 00101 = 4
> > >> [AVBSFContext @ 000000000049b9c0] 206
> max_dec_frame_buffering
> > >> 00101 = 4
> > >>
> > >> Where did 4 come from?  It never uses more than 1 reference in the
> > stream.
> > >
> > > According to codec guys this field filled in by HW and represents
> > > how many frames can be stored in DPB buffer. But in reality HW
> > > encoder will reference one frame at the time.
> >
> > Why set it to 4, then?  That just creates needless incompatibility.
> 
> Codec team answer: "AMF has ability to mark frames as LTR frames and then
> it will be more then one reference candidate."
> 4 is the default and can be changed by avctx->refs.
> 
> >
> > Thanks,
> >
> > - Mark
> > _______________________________________________
> > ffmpeg-devel mailing list
> > ffmpeg-devel at ffmpeg.org
> > http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
> 
> I will update to the latest master and resubmit.
> 
> Thanks,
> Mikhail
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel at ffmpeg.org
> http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


More information about the ffmpeg-devel mailing list