Advertisement
Guest User

Untitled

a guest
Mar 2nd, 2013
62
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Diff 9.60 KB | None | 0 0
  1. From eea790f8175403703be1559f8d725140ca3987bd Mon Sep 17 00:00:00 2001
  2. From: Richard <peper03@yahoo.com>
  3. Date: Tue, 26 Feb 2013 17:31:42 +0100
  4. Subject: [PATCH] Add passing DVD navigation packets (startcode 0x1bf) to
  5.  caller to allow better playback handling of DVDs.  The two
  6.  types of packets (PCI and DSI) are passed untouched but
  7.  combined by the new codec ID AV_CODEC_ID_DVD_NAV.  The
  8.  first 980 bytes in the packet contain the PCI data.  The
  9.  next 1018 are the DSI data.
  10.  
  11. ---
  12. configure                   |    2 +-
  13.  libavcodec/Makefile         |    1 +
  14.  libavcodec/allcodecs.c      |    1 +
  15.  libavcodec/avcodec.h        |    2 +
  16.  libavcodec/codec_desc.c     |    6 +++
  17.  libavcodec/dvd_nav_parser.c |   85 +++++++++++++++++++++++++++++++++++++++++++
  18.  libavcodec/version.h        |    2 +-
  19.  libavformat/mpeg.c          |   28 +++++++++++---
  20.  8 files changed, 120 insertions(+), 7 deletions(-)
  21.  create mode 100644 libavcodec/dvd_nav_parser.c
  22.  
  23. diff --git a/configure b/configure
  24. index f442715..52c3078 100755
  25. --- a/configure
  26. +++ b/configure
  27. @@ -1869,7 +1869,7 @@ wmv3_vdpau_hwaccel_select="vc1_vdpau_hwaccel"
  28.  # parsers
  29.  h264_parser_select="error_resilience golomb h264chroma h264dsp h264pred h264qpel mpegvideo videodsp"
  30.  mpeg4video_parser_select="error_resilience mpegvideo"
  31. -mpegvideo_parser_select="error_resilience mpegvideo"
  32. +mpegvideo_parser_select="error_resilience mpegvideo dvdnav"
  33.  vc1_parser_select="error_resilience mpegvideo"
  34.  
  35.  # external libraries
  36. diff --git a/libavcodec/Makefile b/libavcodec/Makefile
  37. index 52282e3..3b8b277 100644
  38. --- a/libavcodec/Makefile
  39. +++ b/libavcodec/Makefile
  40. @@ -741,6 +741,7 @@ OBJS-$(CONFIG_PNG_PARSER)              += png_parser.o
  41.  OBJS-$(CONFIG_MPEGAUDIO_PARSER)        += mpegaudio_parser.o \
  42.                                            mpegaudiodecheader.o mpegaudiodata.o
  43.  OBJS-$(CONFIG_MPEGVIDEO_PARSER)        += mpegvideo_parser.o    \
  44. +                                          dvd_nav_parser.o \
  45.                                            mpeg12.o mpeg12data.o
  46.  OBJS-$(CONFIG_PNM_PARSER)              += pnm_parser.o pnm.o
  47.  OBJS-$(CONFIG_RV30_PARSER)             += rv34_parser.o
  48. diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c
  49. index 584446f..1eaf2d3 100644
  50. --- a/libavcodec/allcodecs.c
  51. +++ b/libavcodec/allcodecs.c
  52. @@ -515,6 +515,7 @@ void avcodec_register_all(void)
  53.      REGISTER_PARSER(DNXHD,              dnxhd);
  54.      REGISTER_PARSER(DVBSUB,             dvbsub);
  55.      REGISTER_PARSER(DVDSUB,             dvdsub);
  56. +    REGISTER_PARSER(DVD_NAV,            dvd_nav);
  57.      REGISTER_PARSER(FLAC,               flac);
  58.      REGISTER_PARSER(GSM,                gsm);
  59.      REGISTER_PARSER(H261,               h261);
  60. diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
  61. index f809e3d..1e08271 100644
  62. --- a/libavcodec/avcodec.h
  63. +++ b/libavcodec/avcodec.h
  64. @@ -483,6 +483,8 @@ enum AVCodecID {
  65.      AV_CODEC_ID_IDF        = MKBETAG( 0 ,'I','D','F'),
  66.      AV_CODEC_ID_OTF        = MKBETAG( 0 ,'O','T','F'),
  67.      AV_CODEC_ID_SMPTE_KLV  = MKBETAG('K','L','V','A'),
  68. +    AV_CODEC_ID_DVD_NAV    = MKBETAG('D','N','A','V'),
  69. +
  70.  
  71.      AV_CODEC_ID_PROBE = 0x19000, ///< codec_id is not known (like AV_CODEC_ID_NONE) but lavf should attempt to identify it
  72.  
  73. diff --git a/libavcodec/codec_desc.c b/libavcodec/codec_desc.c
  74. index 440e9d9..32db185 100644
  75. --- a/libavcodec/codec_desc.c
  76. +++ b/libavcodec/codec_desc.c
  77. @@ -2523,6 +2523,12 @@ static const AVCodecDescriptor codec_descriptors[] = {
  78.          .name      = "klv",
  79.          .long_name = NULL_IF_CONFIG_SMALL("SMPTE 336M Key-Length-Value (KLV) metadata"),
  80.      },
  81. +    {
  82. +        .id        = AV_CODEC_ID_DVD_NAV,
  83. +        .type      = AVMEDIA_TYPE_DATA,
  84. +        .name      = "dvd_nav_packet",
  85. +        .long_name = NULL_IF_CONFIG_SMALL("DVD Nav packet"),
  86. +    },
  87.  
  88.  };
  89.  
  90. diff --git a/libavcodec/dvd_nav_parser.c b/libavcodec/dvd_nav_parser.c
  91. new file mode 100644
  92. index 0000000..21deb45
  93. --- /dev/null
  94. +++ b/libavcodec/dvd_nav_parser.c
  95. @@ -0,0 +1,85 @@
  96. +/*
  97. + * DVD navigation block parser for FFmpeg
  98. + * Copyright (c) 2013 The ffmpeg Project
  99. + *
  100. + * This file is part of FFmpeg.
  101. + *
  102. + * FFmpeg is free software; you can redistribute it and/or
  103. + * modify it under the terms of the GNU Lesser General Public
  104. + * License as published by the Free Software Foundation; either
  105. + * version 2.1 of the License, or (at your option) any later version.
  106. + *
  107. + * FFmpeg is distributed in the hope that it will be useful,
  108. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  109. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  110. + * Lesser General Public License for more details.
  111. + *
  112. + * You should have received a copy of the GNU Lesser General Public
  113. + * License along with FFmpeg; if not, write to the Free Software
  114. + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  115. + */
  116. +#include "avcodec.h"
  117. +#include "dsputil.h"
  118. +#include "get_bits.h"
  119. +#include "parser.h"
  120. +
  121. +/* parser definition */
  122. +typedef struct DVDNavParseContext {
  123. +    ParseContext pc;
  124. +} DVDNavParseContext;
  125. +
  126. +static int dvd_nav_parse(AVCodecParserContext *s,
  127. +                         AVCodecContext *avctx,
  128. +                         const uint8_t **poutbuf, int *poutbuf_size,
  129. +                         const uint8_t *buf, int buf_size)
  130. +{
  131. +    DVDNavParseContext *pc1 = s->priv_data;
  132. +    ParseContext *pc= &pc1->pc;
  133. +    int next = END_NOT_FOUND;
  134. +    int blockOK = 1;
  135. +
  136. +    s->pict_type = AV_PICTURE_TYPE_NONE;
  137. +
  138. +    avctx->time_base.num = 1;
  139. +    avctx->time_base.den = 90000;
  140. +
  141. +    switch(buf[0])
  142. +    {
  143. +        case 0x00:
  144. +        {
  145. +            /* PCI */
  146. +            uint32_t startpts = AV_RB32(&buf[0x0D]);
  147. +            uint32_t endpts = AV_RB32(&buf[0x11]);
  148. +            s->pts = (int64_t)startpts;
  149. +            s->duration = endpts - startpts;
  150. +        }
  151. +        break;
  152. +
  153. +        case 0x01:
  154. +        {
  155. +            /* DSI */
  156. +            next = buf_size;
  157. +        }
  158. +        break;
  159. +
  160. +        default:
  161. +            blockOK = 0;
  162. +            break;
  163. +    }
  164. +
  165. +    if (!blockOK || ff_combine_frame(pc, next, &buf, &buf_size) < 0) {
  166. +        *poutbuf = NULL;
  167. +        *poutbuf_size = 0;
  168. +        return buf_size;
  169. +    }
  170. +
  171. +    *poutbuf      = buf;
  172. +    *poutbuf_size = buf_size;
  173. +    return next;
  174. +}
  175. +
  176. +AVCodecParser ff_dvd_nav_parser = {
  177. +    .codec_ids      = { AV_CODEC_ID_DVD_NAV },
  178. +    .priv_data_size = sizeof(DVDNavParseContext),
  179. +    .parser_parse   = dvd_nav_parse,
  180. +};
  181. diff --git a/libavcodec/version.h b/libavcodec/version.h
  182. index dceeaa4..b57bcb6 100644
  183. --- a/libavcodec/version.h
  184. +++ b/libavcodec/version.h
  185. @@ -29,7 +29,7 @@
  186.  #include "libavutil/avutil.h"
  187.  
  188.  #define LIBAVCODEC_VERSION_MAJOR 54
  189. -#define LIBAVCODEC_VERSION_MINOR 92
  190. +#define LIBAVCODEC_VERSION_MINOR 93
  191.  #define LIBAVCODEC_VERSION_MICRO 100
  192.  
  193.  #define LIBAVCODEC_VERSION_INT  AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
  194. diff --git a/libavformat/mpeg.c b/libavformat/mpeg.c
  195. index 4eaffd8..98ddc88 100644
  196. --- a/libavformat/mpeg.c
  197. +++ b/libavformat/mpeg.c
  198. @@ -247,9 +247,12 @@ static int mpegps_read_pes_header(AVFormatContext *s,
  199.          goto redo;
  200.      }
  201.      if (startcode == PRIVATE_STREAM_2) {
  202. -        len = avio_rb16(s->pb);
  203. +        int origlen = len = avio_rb16(s->pb);
  204. +        uint8_t firstbyte = avio_r8(s->pb);
  205. +        avio_skip(s->pb, -1);
  206.          if (!m->sofdec) {
  207. -            while (len-- >= 6) {
  208. +            while (len >= 6) {
  209. +                len--;
  210.                  if (avio_r8(s->pb) == 'S') {
  211.                      uint8_t buf[5];
  212.                      avio_read(s->pb, buf, sizeof(buf));
  213. @@ -260,8 +263,15 @@ static int mpegps_read_pes_header(AVFormatContext *s,
  214.              }
  215.              m->sofdec -= !m->sofdec;
  216.          }
  217. -        avio_skip(s->pb, len);
  218. -        goto redo;
  219. +        if (m->sofdec <= 0 &&
  220. +            ((origlen == 980  && firstbyte == 0) ||
  221. +             (origlen == 1018 && firstbyte == 1))) {
  222. +            /* DVD NAV packet, move back to the start of the stream (plus 'length' field) */
  223. +            avio_skip(s->pb, -((origlen-len) + 2));
  224. +        } else {
  225. +            avio_skip(s->pb, len);
  226. +            goto redo;
  227. +        }
  228.      }
  229.      if (startcode == PROGRAM_STREAM_MAP) {
  230.          mpegps_psm_parse(m, s->pb);
  231. @@ -271,7 +281,9 @@ static int mpegps_read_pes_header(AVFormatContext *s,
  232.      /* find matching stream */
  233.      if (!((startcode >= 0x1c0 && startcode <= 0x1df) ||
  234.            (startcode >= 0x1e0 && startcode <= 0x1ef) ||
  235. -          (startcode == 0x1bd) || (startcode == 0x1fd)))
  236. +          (startcode == 0x1bd) ||
  237. +          (startcode == PRIVATE_STREAM_2) ||
  238. +          (startcode == 0x1fd)))
  239.          goto redo;
  240.      if (ppos) {
  241.          *ppos = avio_tell(s->pb) - 4;
  242. @@ -279,6 +291,8 @@ static int mpegps_read_pes_header(AVFormatContext *s,
  243.      len = avio_rb16(s->pb);
  244.      pts =
  245.      dts = AV_NOPTS_VALUE;
  246. +    if (startcode != PRIVATE_STREAM_2)
  247. +    {
  248.      /* stuffing */
  249.      for(;;) {
  250.          if (len < 1)
  251. @@ -352,6 +366,7 @@ static int mpegps_read_pes_header(AVFormatContext *s,
  252.      }
  253.      else if( c!= 0xf )
  254.          goto redo;
  255. +    }
  256.  
  257.      if (startcode == PRIVATE_STREAM_1) {
  258.          startcode = avio_r8(s->pb);
  259. @@ -448,6 +463,9 @@ static int mpegps_read_packet(AVFormatContext *s,
  260.          else
  261.              request_probe= 1;
  262.          type = AVMEDIA_TYPE_VIDEO;
  263. +    } else if (startcode == PRIVATE_STREAM_2) {
  264. +        type = AVMEDIA_TYPE_DATA;
  265. +        codec_id = AV_CODEC_ID_DVD_NAV;
  266.      } else if (startcode >= 0x1c0 && startcode <= 0x1df) {
  267.          type = AVMEDIA_TYPE_AUDIO;
  268.          codec_id = m->sofdec > 0 ? AV_CODEC_ID_ADPCM_ADX : AV_CODEC_ID_MP2;
  269. -- 1.7.9.5
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement