vdr-1.7.29 + h264 MBAFF

Message ID 50583CF5.3050908@tvdr.de
State New
Headers

Commit Message

Klaus Schmidinger Sept. 18, 2012, 9:20 a.m. UTC
  On 17.09.2012 14:17, ????????? ?????? (Pridvorov Andrey) wrote:
> I analyzed the streams.
> I-frame have Sequence Parameter Set always, and NAL type = 7.
>
> My suggestion:
>
> ....
> int FrameTypeOffset = i + 6;//Offset to Sequence parameter set
> if (FrameTypeOffset >= TS_SIZE) // the byte to check is in the next TS
> packet
>         i = SkipPackets(Data, Length, Processed, FrameTypeOffset);
> newFrame = true;
> uchar FrameType = Data[FrameTypeOffset]&0x1F;//NAL Unit Type is last 5 bit
> independentFrame = FrameType == 0x07;//NAL Unit Type = 7 if I-frame
> ...
>
> It's works all time.

That was a very good pointer in the right direction.
However, we can't just blindly look at Data[i + 6], but rather have
to search for a NALU start code after the Access Unit Delimiter.
The attached patch changes cFrameDetector::Analyze() accordingly,
and it still works with the HD channels I have access to, and also
the sample you sent me earlier.

Please try whether this patch works with all the HD channels you can
receive.

I would also appreciate if as many other VDR users as possible applied
this patch and tested it, so that we can be sure it works before I release
the next developer version.

Klaus

> -----Original Message-----
> From: vdr-bounces@linuxtv.org [mailto:vdr-bounces@linuxtv.org] On Behalf Of
> Klaus Schmidinger
> Sent: Friday, September 14, 2012 8:40 AM
> To: vdr@linuxtv.org
> Subject: Re: [vdr] vdr-1.7.29 + h264 MBAFF
>
> On 13.09.2012 23:15, Reinhard Nissl wrote:
>> Hi,
>>
>> Am 13.09.2012 12:25, schrieb Klaus Schmidinger:
>>
>>> On 12.09.2012 17:19, ????????? ?????? (Pridvorov Andrey) wrote:
>>>> Progress display show correct time, but at the end play freeze.
>>>> Other player (on MS windows) play correct.
>>>>
>>>> Try http://rghost.ru/40326577
>>>
>>> It looks like the frame type is 0xF0 for *all* frames of this
>>> stream.
>>> But when I play it on my TT S2-6400 card, even though I can move an
>>> editing mark to every single frame, only every 10th or so frame
>>> is actually
>>> displayed on the tv.
>>>
>>> So my guess is, the frame types are not set correctly in this
>>> stream.
>>> 0xF0 seems bogus to me. So far I have seen only 0x10, 0x30 and
>>> 0x50 (IIRC).
>>
>> Well, testing for the whole byte is not according to the specs, as only
> the upper 3 bits denote primary_pic_type. So the typical primary_pic_types
> are 0, 2 and 4 while 0xF0 yields 7.
>
> So I guess in cFrameDetector::Analyze() it should then be
>
>                                  uchar FrameType = Data[FrameTypeOffset] &
> 0xE0;
>                                  independentFrame = FrameType == 0x00;
>
> which doesn't make much of a difference for this particular case, but
> at least would look at only the valid bits.
>
>> primary_pic_type tells you, which slice_types (among I, SI, P, SP, B) may
> be used to describe the picture, so one can derive the MPEG1/2 I, B and P
> picture type meaning from it for the typical cases.
>>
>> primary_pic_type 7 indicates that all slice types may be used to describe
> the picture, so the best match for a MPEG1/2 picture type would be a B
> picture.
>>
>> Hence, the byte value 0xF0 is valid and correct, but doesn't help
> anyfurther to find independent pictures.
>
> I really wonder what kind of crack the people who came up with this stuff
> have smoked. Why didn't they just put in there a simple, straightforward
> bit that says "an independent picture starts here"?
>
> Klaus
>
>>>> -----Original Message-----
>>>> From: vdr-bounces@linuxtv.org [mailto:vdr-bounces@linuxtv.org]
>>>> On Behalf Of
>>>> Klaus Schmidinger
>>>> Sent: Thursday, September 13, 2012 1:33 AM
>>>> To: vdr@linuxtv.org
>>>> Subject: Re: [vdr] vdr-1.7.29 + h264 MBAFF
>>>>
>>>> On 12.09.2012 16:06, ????????? ?????? (Pridvorov Andrey) wrote:
>>>>> Hi.
>>>>>
>>>>> I have trouble with some h264 HD channels.
>>>>>
>>>>> It have MBAFF scan type, live tv on vdr works, but no recordings.
>>>>>
>>>>> Recorded file have 0 size.
>>>>>
>>>>> But, if in remux.c, in int cFrameDetector::Analyze(const uchar
>>>>> *Data, int
>>>> Length)
>>>>>
>>>>> change
>>>>>
>>>>> independentFrame = FrameType == 0x10
>>>>>
>>>>> to
>>>>>
>>>>> independentFrame = (FrameType == 0x10 || FrameType == 0xf0)
>>>>>
>>>>> Than all recordings fine.
>>>>>
>>>>> Is this correct?
>>>>
>>>> I tend to doubt that.
>>>> What about the progress display when you replay such a recording?
>>>> Does it show the correct times?
>>>>
>>>> Can you make a short recording available for further
>>>> investigation?
>>>>
>>>> Klaus
  

Comments

VDRU VDRU Sept. 18, 2012, 3:07 p.m. UTC | #1
On Tue, Sep 18, 2012 at 2:20 AM, Klaus Schmidinger
<Klaus.Schmidinger@tvdr.de> wrote:
> Please try whether this patch works with all the HD channels you can
> receive.
>
> I would also appreciate if as many other VDR users as possible applied
> this patch and tested it, so that we can be sure it works before I release
> the next developer version.

The patch fails on vanilla .30, do you have other patches applied to
remux.c as well?

/tmp$ tar -jxf vdr-1.7.30.tar.bz2
/tmp/$ cd vdr-1.7.30
/tmp/vdr-1.7.30$ patch -p1 --dry-run <
/ldvb/vdr.patches/vdr-1.7.30-hdframedetect.diff
(Stripping trailing CRs from patch.)
patching file remux.c
Hunk #2 FAILED at 971.
1 out of 2 hunks FAILED -- saving rejects to file remux.c.rej
  

Patch

--- remux.c	2012/09/14 09:06:14	2.65
+++ remux.c	2012/09/18 09:11:24
@@ -843,7 +843,8 @@ 
 
 int cFrameDetector::Analyze(const uchar *Data, int Length)
 {
-  int SeenPayloadStart = false;
+  bool SeenPayloadStart = false;
+  bool SeenAccessUnitDelimiter = false;
   int Processed = 0;
   newFrame = independentFrame = false;
   while (Length >= TS_SIZE) {
@@ -970,12 +971,16 @@ 
                                scanner = EMPTY_SCANNER;
                                if (synced && !SeenPayloadStart && Processed)
                                   return Processed; // flush everything before this new frame
+                               SeenAccessUnitDelimiter = true;
+                               }
+                            else if (SeenAccessUnitDelimiter && scanner == 0x00000001) { // NALU start
+                               SeenAccessUnitDelimiter = false;
                                int FrameTypeOffset = i + 1;
                                if (FrameTypeOffset >= TS_SIZE) // the byte to check is in the next TS packet
                                   i = SkipPackets(Data, Length, Processed, FrameTypeOffset);
                                newFrame = true;
-                               uchar FrameType = Data[FrameTypeOffset] & 0xE0;
-                               independentFrame = FrameType == 0x00;
+                               uchar FrameType = Data[FrameTypeOffset] & 0x1F;
+                               independentFrame = FrameType == 0x07;
                                if (synced) {
                                   if (framesPerPayloadUnit < 0) {
                                      payloadUnitOfFrame = (payloadUnitOfFrame + 1) % -framesPerPayloadUnit;