GNOME Bugzilla – Bug 595286
[ffdec_dvvideo] doesn't handle PAR correctly
Last modified: 2012-12-12 09:26:34 UTC
If I decode a dv video with HEAD gstreamer, I get this: $ gst-launch -v filesrc location=/kipple/lumroom.mov ! decodebin ! video/x-raw-yuv ! fakesink ... /GstPipeline:pipeline0/GstDecodeBin:decodebin0/ffdec_dvvideo:ffdec_dvvideo0.GstPad:src: caps = video/x-raw-yuv, width=(int)720, height=(int)480, framerate=(fraction)2997/100, format=(fourcc)Y41B, interlaced=(boolean)true ... Yet if I edit the dvdec source code to make the libdv decoder PRIMARY instead of MARGINAL, I get this: $ gst-launch -v filesrc location=/kipple/lumroom.mov ! decodebin ! video/x-raw-yuv ! fakesink ... /GstPipeline:pipeline0/GstDecodeBin:decodebin0/GstDVDec:dvdec0.GstPad:src: caps = video/x-raw-yuv, format=(fourcc)YUY2, width=(int)720, height=(int)480, framerate=(fraction)2997/100, pixel-aspect-ratio=(fraction)10/11, interlaced=(boolean)true Note the difference? PAR is correctly set in the libdv case, and not in the ffmpeg case. I think the right thing is to either fix gst-ffmpeg, or revert this one: commit 268b93fd1e24f9b2d94b37500234bba0525642e6 Author: Edward Hervey <bilboed@bilboed.com> Date: Thu Jun 26 09:37:23 2008 +0000 ext/dv/gstdv.c: Marking rank of dvdec as GST_RANK_MARGINAL since it's the slowest Original commit message from CVS: * ext/dv/gstdv.c: (plugin_init): Marking rank of dvdec as GST_RANK_MARGINAL since it's the slowest DV decoder available. Fixes #532393
fail fail mpeg ... indeed... they must think that PAR is useless for DV :( It also fails with mplayer, haven't tried with other players. Basically the ffmpeg dv decoder doesn't set the output sample_aspect_ratio structure. Dunno what to do...
Fix ffmpeg, that shouldn't be too hard I guess ;) Then it's the fastest dv decoder and as feature complete as dvdec.
I propose to give dvdec PRIMARY rank again until this gets fixed in ffmpeg or gst-ffmpeg. Correctness is more important than speed IMHO.
Feel free to use this code in gst-ffmpeg and modify as necessary. If is_wide is false, par is 10/11 (NTSC) or 12/11 (PAL). If is_wide is true, multiply that by 4/3. is_422 is not relevant here, interlaced and top_field_first are useful too. dvdec doesn't handle a lot of the DV varieties that ffdec_dv does. /* Copyright 2009 Entropy Wave Inc, used with permission */ static int get_vaux_offset (int dif, int vaux) { int offset; offset = dif * 12000; /* to dif */ offset += 80 * (3 + (vaux / 15)); /* to subcode pack */ offset += 3; /* past header */ offset += 5 * (vaux % 15); /* to vaux */ return offset; } static void get_info (EwDVDec *decoder, const guint8 *data) { int offset; int dif; int n_difs = decoder->is_625 ? 12 : 10; for(dif=0;dif<n_difs;dif++) { offset = get_vaux_offset (dif, (dif&1) ? 0 : 39); GST_DEBUG("%02x",data[offset + 0]); if (data[offset + 0] == 0x60) { if ((data[offset + 3] & 0x1f) == 4) { GST_DEBUG("4:2:2 compression"); decoder->is_422 = TRUE; } else { decoder->is_422 = FALSE; } break; } } if (dif==n_difs) { GST_ERROR("failed to find VAUX source pack"); } for(dif=0;dif<n_difs;dif++) { offset = get_vaux_offset (dif, (dif&1) ? 1 : 40); GST_DEBUG("%02x",data[offset + 0]); if (data[offset + 0] == 0x61) { if ((data[offset + 2] & 7) == 2) { decoder->is_wide = TRUE; } else { decoder->is_wide = FALSE; } if (data[offset + 3] & 0x10) { decoder->base_video_decoder.state.interlaced = TRUE; } else { decoder->base_video_decoder.state.interlaced = FALSE; } GST_DEBUG("is_wide %d interlaced %d", decoder->is_wide, decoder->base_video_decoder.state.interlaced); break; } } if (dif==n_difs) { GST_ERROR("failed to find VAUX source control pack"); } decoder->base_video_decoder.state.top_field_first = FALSE; }
> dvdec doesn't handle a lot of the DV varieties that ffdec_dv does. Ah, I wasn't aware of that. Moving to (gst-)ffmpeg then.
*** Bug 635122 has been marked as a duplicate of this bug. ***
Seems to work fine now.