Mailing List archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: AV_PES format - How can I detect frames?



David Podeur wrote:
> 
> * Thomas 'Dent' Mirlacher <dent@cosy.sbg.ac.at> [000328 21:58]
> 
> > > Well, actually GROUP_START_CODE is 0x000001b5, and SEQUENCE_HEADER_CODE
> > > is 0x000001b3. Unlike in MPEG-1, no GOPs are required in MPEG-2 (this
> > > can occur in some weard cases, but i've never seen it in the DVB-S
> > > MPEG-2 signal).
> 
> > right. - thanks david - i've to admit i'm not a video guy ;)
> 
> Not so right ;) i did antoher mistake in the codes...
> 
> So let's repeat the whole thing:
>  GROUP_START_CODE     -> b8 (not that usefull in MPEG-2)
>  SEQUENCE_START_CODE  -> b3 (seems to appear every second in the signal)
>  EXTENSION_START_CODE -> b5 (main difference between MPEG-1 and 2)
>  PICTURE_START_CODE   -> 00 (picture start)
> 
> > > I am still looking for the "missing" frames, i'll tell you when i find
> > > them...
> 
> > huh? missing frames?? ;)
> 
> I can find only between 11 and 13 PICTURE_START_CODE between two
> SEQUENCE_START_CODE, so i wonder how to get the rest of the pictures to
> reach the frame rate of 25. Ideas?

I finally managed to take a look into the ISO/IEC 13818-2 and found that
the 0x000001 start code may be preceeded by any number of 0x00. So I modified
my small test program and now it detects all 49500 frames expected to be found
in a 33 minute recording.

I have attached the modified program version, for those interested.

Klaus Schmidinger
-- 
_______________________________________________________________

Klaus Schmidinger                       Phone: +49-8635-6989-10
CadSoft Computer GmbH                   Fax:   +49-8635-6989-40
Hofmark 2                               Email:   kls@cadsoft.de
D-84568 Pleiskirchen, Germany           URL:     www.cadsoft.de
_______________________________________________________________
    [ Part 2: "Attached Text" ]

/*

This program detects the data blocks in an AV_PES data stream.

AV_PES data format:

'A'  'V'  t  n  'U'  g  ll  d d d ...

where

- '*' are literal characters
- t   is the type (1 = Video, 2 = Audio)
- n   is a sequence number (0..255, wrapping)
- g   is a "gap" number (don't know what it means)
- ll  is the two byte length of data (high byte first)
- d   is the actual video or audio data

*/

#include <fcntl.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

#define SHOWBYTES 40
 
typedef unsigned char uchar;
typedef unsigned short ushort;

struct tAVPES {
  uchar AV[2];
  uchar t;
  uchar n;
  uchar U;
  uchar g;
  ushort ll;
  bool IsHeader(void) { return AV[0] == 'A' && AV[1] == 'V' && (t == 1 || t == 2) && U == 'U'; }
  ushort Length(void) { return ntohs(ll); }
  };

int main(int argc, char *argv[])
{
  if (argc > 2)
     return 1;

  int f = argc == 2 ? open(argv[1], O_RDONLY) : fileno(stdin);

  if (f >= 0) {
     unsigned char *d = NULL;
     tAVPES a;
     int r;
     while ((r = read(f, &a, sizeof(a))) == sizeof(a)) {
           if (a.IsHeader()) {
              ushort l = a.Length();
              //printf("%c%c %d %3d %c %02X %5d", a.AV[0], a.AV[1], a.t, a.n, a.U, a.g, l);
              d = (unsigned char *)realloc(d, l);
              int rd;
              if ((rd = read(f, d, l)) == l) {
                 //for (int i = 0; i < SHOWBYTES; i++)
                 //    printf(" %02X", d[i]);
                 if (a.t == 2)
                    continue;
                 for (int i = 0; i < l - 3; i++) {
                     if (d[i] == 0 && d[i + 1] == 0 && d[i + 2] == 1 && d[i + 3] == 0) {
                        printf("%c%c %d %3d %c %02X %5d", a.AV[0], a.AV[1], a.t, a.n, a.U, a.g, l);
                        for (int j = 0; j < SHOWBYTES; j++)
                            printf(" %02X", d[j]);
                        printf(" - %02X %02X", d[i + 5], (d[i + 5] >> 3) & 0x07);
                        printf("\n");
                        }
                     }
                 //printf("\n");
                 }
              else
                 break;
              }
           else
              lseek(f, -(r - 1), SEEK_CUR);
           }
     }
  else
     fprintf(stderr, "can't open '%s'\n", argv[1]);
  return 0;
}


Home | Main Index | Thread Index