[PATCH] Port VDPAU to AVHWAccel infrastructure
Hi, This patch moves VDPAU code to AVHWAccel. An older version (without MPEG-4 ASP) was already tested by NVIDIA. However, - A separate patch would remove vdpau_internal.h - I don't know what to do with older pixfmts since they are now completely obsolete and useless (the hwaccel v2 proposal nukes all pixfmts anyway) - It's a plain and straightforward port, no effort was made to fix current bugs in the VDPAU code (including the memory leaks) Regards, Gwenole.
On Tue, Dec 29, 2009 at 10:25:37AM +0100, Gwenole Beauchesne wrote:
Hi,
This patch moves VDPAU code to AVHWAccel. An older version (without MPEG-4 ASP) was already tested by NVIDIA. However, - A separate patch would remove vdpau_internal.h - I don't know what to do with older pixfmts since they are now completely obsolete and useless (the hwaccel v2 proposal nukes all pixfmts anyway) - It's a plain and straightforward port, no effort was made to fix current bugs in the VDPAU code (including the memory leaks)
VC-1 part is ok
Regards, Gwenole.
On Tue, Dec 29, 2009 at 10:25:37AM +0100, Gwenole Beauchesne wrote:
Hi,
This patch moves VDPAU code to AVHWAccel. An older version (without MPEG-4 ASP) was already tested by NVIDIA. However, - A separate patch would remove vdpau_internal.h - I don't know what to do with older pixfmts since they are now completely obsolete and useless (the hwaccel v2 proposal nukes all pixfmts anyway) - It's a plain and straightforward port, no effort was made to fix current bugs in the VDPAU code (including the memory leaks)
[...]
--- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.h @@ -613,10 +613,6 @@ typedef struct RcOverride{ */ #define CODEC_CAP_SMALL_LAST_FRAME 0x0040 /** - * Codec can export data for HW decoding (VDPAU). - */ -#define CODEC_CAP_HWACCEL_VDPAU 0x0080 -/** * Codec can output multiple frames per AVPacket */
breaks API, this must be delayed until the next major bump with #if ... [...]
+static void vdpau_h264_fill_picture(VdpReferenceFrameH264 *rf, Picture *pic, int pic_structure) +{ + struct vdpau_render_state *render; + + assert(rf); + assert(pic); + + if (pic_structure == 0) + pic_structure = pic->reference; + + render = (struct vdpau_render_state *)pic->data[3]; + assert(render);
lots of new asserts(), these dont belong in this patch [...]
@@ -84,70 +125,92 @@ void ff_vdpau_h264_set_reference_frames(MpegEncContext *s) if (rf >= &render->info.h264.referenceFrames[H264_RF_COUNT]) continue;
- rf->surface = render_ref->surface; - rf->is_long_term = pic->long_ref; - rf->top_is_reference = (pic->reference & PICT_TOP_FIELD) ? VDP_TRUE : VDP_FALSE; - rf->bottom_is_reference = (pic->reference & PICT_BOTTOM_FIELD) ? VDP_TRUE : VDP_FALSE; - rf->field_order_cnt[0] = pic->field_poc[0]; - rf->field_order_cnt[1] = pic->field_poc[1]; - rf->frame_idx = pic_frame_idx; + vdpau_h264_fill_picture(rf, pic, pic->reference);
factorizing this out into a function does not belong in this patch
++rf; } }
- for (; rf < &render->info.h264.referenceFrames[H264_RF_COUNT]; ++rf) { - rf->surface = VDP_INVALID_HANDLE; - rf->is_long_term = 0; - rf->top_is_reference = 0; - rf->bottom_is_reference = 0; - rf->field_order_cnt[0] = 0; - rf->field_order_cnt[1] = 0; - rf->frame_idx = 0; - } + for (; rf < &render->info.h264.referenceFrames[H264_RF_COUNT]; ++rf) + vdpau_h264_init_picture(rf);
same [...]
+static int vdpau_common_start_frame(AVCodecContext *avctx, av_unused const uint8_t *buffer, av_unused uint32_t size) +{ + MpegEncContext * const s = avctx->priv_data;
+ struct vdpau_render_state *render; + + render = (struct vdpau_render_state *)s->current_picture_ptr->data[3];
can be merged
+ assert(render);
useless, it will crash on the next line anyway if its NULL that is unless this code is moved around in which case the assert should stay for the time. It could be removed in a future patch [...]
- render->info.h264.is_reference = (s->current_picture_ptr->reference & 3) ? VDP_TRUE : VDP_FALSE; + /* fill VdpPictureInfoH264 struct */ + render->info.h264.is_reference = h->nal_ref_idc != 0;
why? [...] also i assume this is tested and works? and it needs approval from carl as well as he is VDPAU maintainer -- Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB When the tyrant has disposed of foreign enemies by conquest or treaty, and there is nothing more to fear from them, then he is always stirring up some war or other, in order that the people may require a leader. -- Plato
Hi, On Sun, 3 Jan 2010, Michael Niedermayer wrote:
[...]
--- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.h @@ -613,10 +613,6 @@ typedef struct RcOverride{ */ #define CODEC_CAP_SMALL_LAST_FRAME 0x0040 /** - * Codec can export data for HW decoding (VDPAU). - */ -#define CODEC_CAP_HWACCEL_VDPAU 0x0080 -/** * Codec can output multiple frames per AVPacket */
breaks API, this must be delayed until the next major bump with #if ...
Yes, but porting to hwaccel also breaks the API. Anyway, I dropped this part from the patch.
[...]
+static int vdpau_common_start_frame(AVCodecContext *avctx, av_unused const uint8_t *buffer, av_unused uint32_t size) +{ + MpegEncContext * const s = avctx->priv_data;
+ struct vdpau_render_state *render; + + render = (struct vdpau_render_state *)s->current_picture_ptr->data[3];
can be merged
Done but this was the existing practise.
[...]
- render->info.h264.is_reference = (s->current_picture_ptr->reference & 3) ? VDP_TRUE : VDP_FALSE; + /* fill VdpPictureInfoH264 struct */ + render->info.h264.is_reference = h->nal_ref_idc != 0;
why?
At the point AVHWAccel.start_frame() is called, CurrPic->reference is not initialized yet so this information will be wrong.
[...] also i assume this is tested and works?
This is tested with the usual clips I have. NVIDIA probably had more. New patch attached, reduced by 100 lines. Regards, Gwenole.
On Mon, Jan 04, 2010 at 11:28:47AM +0100, Gwenole Beauchesne wrote:
Hi, [...]
New patch attached, reduced by 100 lines.
Regards, Gwenole.
VC-1 part still OK.
On date Monday 2010-01-04 11:28:47 +0100, Gwenole Beauchesne encoded: [...]
diff --git a/libavutil/pixfmt.h b/libavutil/pixfmt.h index ddd17fb..1f17073 100644 --- a/libavutil/pixfmt.h +++ b/libavutil/pixfmt.h @@ -124,6 +124,7 @@ enum PixelFormat { PIX_FMT_YUV444P16LE, ///< planar YUV 4:4:4, 48bpp, (1 Cr & Cb sample per 1x1 Y samples), little-endian PIX_FMT_YUV444P16BE, ///< planar YUV 4:4:4, 48bpp, (1 Cr & Cb sample per 1x1 Y samples), big-endian PIX_FMT_VDPAU_MPEG4, ///< MPEG4 HW decoding with VDPAU, data[0] contains a vdpau_render_state struct which contains the bitstream of the slices as well as various fields extracted from headers + PIX_FMT_VDPAU, ///< HW decoding with VDPAU, data[3] contains a vdpau_render_state struct which contains the bitstream of the slices as well as various fields extracted from headers PIX_FMT_NB, ///< number of pixel formats, DO NOT USE THIS if you want to link with shared libav* because the number of formats might differ between versions };
Missing libavutil/pixdesc.c entry addition. Also maybe the already existing PIX_FMT_VDPAU_ defines should be marked for deletion at the next major bump. Regards. -- FFmpeg = Fast and Fantastic Mystic Powerful Extended God
On Mon, Jan 04, 2010 at 12:28:02PM +0100, Stefano Sabatini wrote:
On date Monday 2010-01-04 11:28:47 +0100, Gwenole Beauchesne encoded: [...]
diff --git a/libavutil/pixfmt.h b/libavutil/pixfmt.h index ddd17fb..1f17073 100644 --- a/libavutil/pixfmt.h +++ b/libavutil/pixfmt.h @@ -124,6 +124,7 @@ enum PixelFormat { PIX_FMT_YUV444P16LE, ///< planar YUV 4:4:4, 48bpp, (1 Cr & Cb sample per 1x1 Y samples), little-endian PIX_FMT_YUV444P16BE, ///< planar YUV 4:4:4, 48bpp, (1 Cr & Cb sample per 1x1 Y samples), big-endian PIX_FMT_VDPAU_MPEG4, ///< MPEG4 HW decoding with VDPAU, data[0] contains a vdpau_render_state struct which contains the bitstream of the slices as well as various fields extracted from headers + PIX_FMT_VDPAU, ///< HW decoding with VDPAU, data[3] contains a vdpau_render_state struct which contains the bitstream of the slices as well as various fields extracted from headers PIX_FMT_NB, ///< number of pixel formats, DO NOT USE THIS if you want to link with shared libav* because the number of formats might differ between versions };
Missing libavutil/pixdesc.c entry addition.
Also maybe the already existing PIX_FMT_VDPAU_ defines should be marked for deletion at the next major bump.
Before that is done: is this new pixfmt scheme actually used anywhere and proven to work? Because I only know the MPlayer patch and that uses the codec id to generate the "old" scheme. If we get rid of codec-specific pixfmts just so that every single application actually using them has to add their own hacks to get back to the old API again that would just be really idiotic.
Before that is done: is this new pixfmt scheme actually used anywhere and proven to work? Because I only know the MPlayer patch and that uses the codec id to generate the "old" scheme. If we get rid of codec-specific pixfmts just so that every single application actually using them has to add their own hacks to get back to the old API again that would just be really idiotic.
I've started using it for dxva, and it does seem to work there. One rather annoying but thou.. If ffmpeg is compiled without dxva/vdpau support. get_format will currently still ask for the dxva/vdpau pixformat's, fooling the app that those can be used. Fixing it is not entirely straight forward as for example vaapi supports multiple codecs, which can be disabled separate. And currently all of those formats use a single list for which pix_fmt's the have (ff_hwaccel_pixfmt_list_420). So one would have to split that list into separate for each codec to be able to ifdef out what has been enabled.
On Sat, Jan 23, 2010 at 05:37:00PM +0000, Joakim Plate wrote:
Before that is done: is this new pixfmt scheme actually used anywhere and proven to work? Because I only know the MPlayer patch and that uses the codec id to generate the "old" scheme. If we get rid of codec-specific pixfmts just so that every single application actually using them has to add their own hacks to get back to the old API again that would just be really idiotic.
I've started using it for dxva, and it does seem to work there. One rather annoying but thou..
Well, just what I was what that wherever there was a check for the pix_fmt there would also be a check for the CODEC_ID, which I think is wrong, to be able to use an AVFrame you shouldn't need to remember which codec created the AVFrame, it should be usable on its own. I'm not saying this isn't possible with those PIXFMT schemes, I just don't know.
On Sat, Jan 23, 2010 at 05:37:00PM +0000, Joakim Plate wrote:
Before that is done: is this new pixfmt scheme actually used anywhere and proven to work? Because I only know the MPlayer patch and that uses the codec id to generate the "old" scheme. If we get rid of codec-specific pixfmts just so that every single application actually using them has to add their own hacks to get back to the old API again that would just be really idiotic.
I've started using it for dxva, and it does seem to work there. One rather annoying but thou..
If ffmpeg is compiled without dxva/vdpau support. get_format will currently still ask for the dxva/vdpau pixformat's, fooling the app that those can be used.
Fixing it is not entirely straight forward as for example vaapi supports multiple codecs, which can be disabled separate. And currently all of those formats use a single list for which pix_fmt's the have (ff_hwaccel_pixfmt_list_420).
So one would have to split that list into separate for each codec to be able to ifdef out what has been enabled.
yes, patch welcome [...] -- Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB Good people do not need laws to tell them to act responsibly, while bad people will find a way around the laws. -- Plato
Gwenole Beauchesne <gbeauchesne <at> splitted-desktop.com> writes:
- It's a plain and straightforward port, no effort was made to fix current bugs in the VDPAU code
Would you mind reporting them?
(including the memory leaks)
and those? Just two quick questions:
- render->info.h264.is_reference = (s->current_picture_ptr->reference & 3) ? VDP_TRUE : VDP_FALSE; + render->info.h264.is_reference = h->nal_ref_idc != 0;
How is this related to the rest of the patch? [...]
- if (!s->current_picture_ptr) return; + if (!s->current_picture_ptr) return 0;
And this? [...] + /* fill VdpPictureInfoH264 struct */ + /* fill VdpPictureInfoVC1 struct */ Please apply if you think those improve readability. Carl Eugen
Gwenole Beauchesne <gbeauchesne <at> splitted-desktop.com> writes:
Hi,
This patch moves VDPAU code to AVHWAccel. An older version (without MPEG-4 ASP) was already tested by NVIDIA. However, - A separate patch would remove vdpau_internal.h - I don't know what to do with older pixfmts since they are now completely obsolete and useless (the hwaccel v2 proposal nukes all pixfmts anyway)
Bump... Just ran into an issue with the old system that this would have handled just fine. In old system one needs to know height/width of video from demuxer to check for hw support of a specific width/height (for some silly reason some nvidia chipsets have issues with some video widths). If demuxer doesn't provide this info, one would have to start decoding without hw support to find this out. With the system, the init of vdpau is delayed untill we have started decoding bitstream and know it's width/height.
participants (7)
-
cehoyos@ag.or.at -
elupus@ecce.se -
gbeauchesne@splitted-desktop.com -
kostya.shishkov@gmail.com -
michaelni@gmx.at -
Reimar.Doeffinger@gmx.de -
stefano.sabatini-lala@poste.it