[FFmpeg-devel] [RFC/PATCH] Pass PRIVATE_STREAM_2 MPEG-PS packets to caller

Michael Niedermayer michaelni at gmx.at
Sun Mar 3 01:55:33 CET 2013


On Sun, Mar 03, 2013 at 12:51:46AM +0100, Richard wrote:
> On 02/03/13 13:18, Michael Niedermayer wrote:
[...]
> +static int dvd_nav_parse(AVCodecParserContext *s,
> +                         AVCodecContext *avctx,
> +                         const uint8_t **poutbuf, int *poutbuf_size,
> +                         const uint8_t *buf, int buf_size)
> +{
> +    DVDNavParseContext *pc1 = s->priv_data;
> +    ParseContext *pc        = &pc1->pc;
> +    int lastPacket          = 0;
> +    int valid               = 0;
> +
> +    s->pict_type = AV_PICTURE_TYPE_NONE;
> +

> +    avctx->time_base.num = 1;
> +    avctx->time_base.den = 90000;

why is this needed ?


> +
> +    if (buf && buf_size)
> +    {
> +        switch(buf[0])
> +        {
> +            case 0x00:
> +            {
> +                if (buf_size == PCI_SIZE) {
> +                    /* PCI */
> +                    uint32_t lba      = AV_RB32(&buf[0x01]);
> +                    uint32_t startpts = AV_RB32(&buf[0x0D]);
> +                    uint32_t endpts   = AV_RB32(&buf[0x11]);
> +
> +                    if (endpts > startpts)
> +                    {
> +                        pc1->lba    = lba;
> +                        s->pts      = (int64_t)startpts;
> +                        s->duration = endpts - startpts;
> +
> +                        memcpy(pc1->buffer, buf, PCI_SIZE);
> +                        pc1->copied = PCI_SIZE;
> +                        valid       = 1;
> +                    }
> +                }
> +            }
> +            break;
> +
> +            case 0x01:
> +            {
> +                if ((buf_size == DSI_SIZE) && (pc1->copied == PCI_SIZE)) {
> +                    /* DSI */
> +                    uint32_t lba = AV_RB32(&buf[0x05]);
> +
> +                    if (lba == pc1->lba)
> +                    {
> +                        memcpy(pc1->buffer + pc1->copied, buf, DSI_SIZE);
> +                        lastPacket  = 1;
> +                        valid       = 1;
> +                    }
> +                }
> +            }
> +            break;
> +

> +            default:
> +                break;

unneeded


> +        }
> +    }
> +
> +    if (!valid || lastPacket) {
> +        pc1->copied = 0;
> +        pc1->lba    = 0xFFFFFFFF;
> +    }

the {} placement in this file is rather inconsistent



> +
> +    if (lastPacket) {
> +        *poutbuf      = pc1->buffer;
> +        *poutbuf_size = sizeof(pc1->buffer);
> +    } else {
> +        *poutbuf      = NULL;
> +        *poutbuf_size = 0;
> +    }
> +
> +    return buf_size;
> +}
> +
> +AVCodecParser ff_dvd_nav_parser = {
> +    .codec_ids      = { AV_CODEC_ID_DVD_NAV },
> +    .priv_data_size = sizeof(DVDNavParseContext),
> +    .parser_init    = dvd_nav_parse_init,
> +    .parser_parse   = dvd_nav_parse,
> +};
> diff --git a/libavcodec/version.h b/libavcodec/version.h
> index dceeaa4..b57bcb6 100644
> --- a/libavcodec/version.h
> +++ b/libavcodec/version.h
> @@ -29,7 +29,7 @@
>  #include "libavutil/avutil.h"
>  
>  #define LIBAVCODEC_VERSION_MAJOR 54
> -#define LIBAVCODEC_VERSION_MINOR 92
> +#define LIBAVCODEC_VERSION_MINOR 93
>  #define LIBAVCODEC_VERSION_MICRO 100
>  
>  #define LIBAVCODEC_VERSION_INT  AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
> diff --git a/libavformat/mpeg.c b/libavformat/mpeg.c
> index 4eaffd8..98ddc88 100644
> --- a/libavformat/mpeg.c
> +++ b/libavformat/mpeg.c
> @@ -247,9 +247,12 @@ static int mpegps_read_pes_header(AVFormatContext *s,
>          goto redo;
>      }
>      if (startcode == PRIVATE_STREAM_2) {
> -        len = avio_rb16(s->pb);
> +        int origlen = len = avio_rb16(s->pb);
> +        uint8_t firstbyte = avio_r8(s->pb);
> +        avio_skip(s->pb, -1);
>          if (!m->sofdec) {
> -            while (len-- >= 6) {
> +            while (len >= 6) {
> +                len--;
>                  if (avio_r8(s->pb) == 'S') {
>                      uint8_t buf[5];
>                      avio_read(s->pb, buf, sizeof(buf));
> @@ -260,8 +263,15 @@ static int mpegps_read_pes_header(AVFormatContext *s,
>              }
>              m->sofdec -= !m->sofdec;
>          }
> -        avio_skip(s->pb, len);
> -        goto redo;
> +        if (m->sofdec <= 0 &&
> +            ((origlen == 980  && firstbyte == 0) ||
> +             (origlen == 1018 && firstbyte == 1))) {
> +            /* DVD NAV packet, move back to the start of the stream (plus 'length' field) */

> +            avio_skip(s->pb, -((origlen-len) + 2));

this seeks backward which is not guranteed to work on non seekable
protocols. On a dvd it would work but might if the OS cannot satisfy
it from some cache do an actual seek which is slow.
the same issue exists a fiw lines above
 
[...]

-- 
Michael     GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB

The bravest are surely those who have the clearest vision
of what is before them, glory and danger alike, and yet
notwithstanding go out to meet it. -- Thucydides
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 198 bytes
Desc: Digital signature
URL: <http://ffmpeg.org/pipermail/ffmpeg-devel/attachments/20130303/74265305/attachment.asc>


More information about the ffmpeg-devel mailing list