[FFmpeg-devel] [PATCH v11 1/3] libavcodec/dnxucdec: DNxUncompressed decoder
Martin Schitter
ms+git at mur.at
Fri Oct 11 17:12:54 EEST 2024
On 11.10.24 10:57, Anton Khirnov wrote:
It seems rather obvious to me - you're making a demuxer export something
> that IS raw video, yet you're tagging it as a new codec ID with a new
> decoder that (for these specific pixel format) duplicates what the
> rawvideo decoder does.
>
> Just to be clear, I'm not saying the entirety of your decoder should be
> handled in the demuxer - just those pixel formats that can be. That
> would also have the advantage that the remainder of your decoder could
> now enable direct rendering.
**Wherever it is possible** I simply set the correct pixel format found
by the dnxuc_parser in avcontext and use a simple pass_through()
routine to transfer the raw packet data without any further processing
as frame data!
That's more or less the same mechanism as used in
libavcodec/bitpacked_dec.c for uyvy422 data.
But if you look at the central dispatcher in my decoder, you'll see,
that this pass_through solution can be only used in 2 cases of the 8
already supported kinds of payload. For all other types of data there is
simply no exact fitting ffmpeg pixel format available or it doesn't work
satisfying in practice.
In the case of all 10 and 12bit variants DNxUncmpressed uses a very
uncommon kind of line-based bitpacking, which you will hardly find
somewhere else. This has to be preprocessed and translated into more
common binary arrangements by this decoder.
But in case of the float variants I had to fight missing support and
disappointing defects in swscaler.
>>>> +static int float2planes(AVCodecContext *avctx, AVFrame *frame, const AVPacket *pkt)
>>>> +{
>>>> + int lw;
>>>> + const size_t sof = 4;
>>>> +
>>>> + lw = frame->width;
>>>> +
>>>> + for(int y = 0; y < frame->height; y++){
>>>> + for(int x = 0; x < frame->width; x++){
>>>> + memcpy(&frame->data[2][sof*(lw*y + x)], &pkt->data[sof* 3*(lw*y + x)], sof);
>>>> + memcpy(&frame->data[0][sof*(lw*y + x)], &pkt->data[sof*(3*(lw*y + x) + 1)], sof);
>>>> + memcpy(&frame->data[1][sof*(lw*y + x)], &pkt->data[sof*(3*(lw*y + x) + 2)], sof);
>>>> + }
>>>> + }
>>>
>>> Same here, deinterleaving packed to planar is a job for swscale.
Do you really think, I'm a stupid idiot and didn't try to handle it in
this much more simple unmodified manner first?
Sure, I did!!
But I immediately stumbled again over another nasty swscale related bug! :(
Just try it yourself:
First make a simple test with my last posted patch set:
./ffmpeg_g -i ./fate-suite/dnxuc/cb_rgb_float.mxf -c:v prores
/tmp/out.mov
everything should simply work as expected
And now change line 348 of dnxucdec.c for float32 sub-format:
case MKTAG(' ','r','g','f'):
- ret = fmt_frame(avctx, frame, avpkt, AV_PIX_FMT_GBRPF32LE,
96, float2planes);
+ ret = fmt_frame(avctx, frame, avpkt, AV_PIX_FMT_RGBF32LE,
96, pass_through);
Now it's using the pass_through() mechanism and utilizes unmodified
packed float input data instead of this clumsy rearrangement, but the
same simple test command as before will not work anymore!
You'll get an error report, that ffmpeg couldn't figure out any working
pipeline resp. pixel format transformation to connect the input data
with anything else...
[vist#0:0/dnxuc @ 0x55e980fd7a00] [dec:dnxuc @ 0x55e981460f40] Decoder
thread received EOF packet
[graph -1 input from stream 0:0 @ 0x7fb644002380] w:512 h:256
pixfmt:rgbf32le tb:1/24 fr:24/1 sar:1/1 csp:bt709 range:unknown
[format @ 0x7fb6440029c0] Setting 'pix_fmts' to value
'yuv422p10le|yuv444p10le|yuva444p10le'
[format @ 0x7fb6440029c0] Setting 'color_ranges' to value 'tv'
[auto_scale_0 @ 0x7fb644004340] w:iw h:ih flags:'' interl:0
[format @ 0x7fb6440029c0] auto-inserting filter 'auto_scale_0' between
the filter 'Parsed_null_0' and the filter 'format'
Impossible to convert between the formats supported by the filter
'Parsed_null_0' and the filter 'auto_scale_0'
That's why I had to add this crazy workaround in this particular case!
But I already told you about all these really disappointing experiences:
>> Some of these rather inefficient interleave<->planar conversions where
>> just necessary in practice, because swscale wasn't able to figure out a
>> working pipeline construction otherwise, although in theory the affected
>> pixel format closer to the data input should be supported and work as
>> well!:(
>>
>> At the end I just looked for something that simply works in real world, too!
>
> But we do have a packed RGBF32 pixel format, how is it different from
> this?
Martin
More information about the ffmpeg-devel
mailing list