Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- From eea790f8175403703be1559f8d725140ca3987bd Mon Sep 17 00:00:00 2001
- From: Richard <peper03@yahoo.com>
- Date: Tue, 26 Feb 2013 17:31:42 +0100
- Subject: [PATCH] Add passing DVD navigation packets (startcode 0x1bf) to
- caller to allow better playback handling of DVDs. The two
- types of packets (PCI and DSI) are passed untouched but
- combined by the new codec ID AV_CODEC_ID_DVD_NAV. The
- first 980 bytes in the packet contain the PCI data. The
- next 1018 are the DSI data.
- ---
- configure | 2 +-
- libavcodec/Makefile | 1 +
- libavcodec/allcodecs.c | 1 +
- libavcodec/avcodec.h | 2 +
- libavcodec/codec_desc.c | 6 +++
- libavcodec/dvd_nav_parser.c | 85 +++++++++++++++++++++++++++++++++++++++++++
- libavcodec/version.h | 2 +-
- libavformat/mpeg.c | 28 +++++++++++---
- 8 files changed, 120 insertions(+), 7 deletions(-)
- create mode 100644 libavcodec/dvd_nav_parser.c
- diff --git a/configure b/configure
- index f442715..52c3078 100755
- --- a/configure
- +++ b/configure
- @@ -1869,7 +1869,7 @@ wmv3_vdpau_hwaccel_select="vc1_vdpau_hwaccel"
- # parsers
- h264_parser_select="error_resilience golomb h264chroma h264dsp h264pred h264qpel mpegvideo videodsp"
- mpeg4video_parser_select="error_resilience mpegvideo"
- -mpegvideo_parser_select="error_resilience mpegvideo"
- +mpegvideo_parser_select="error_resilience mpegvideo dvdnav"
- vc1_parser_select="error_resilience mpegvideo"
- # external libraries
- diff --git a/libavcodec/Makefile b/libavcodec/Makefile
- index 52282e3..3b8b277 100644
- --- a/libavcodec/Makefile
- +++ b/libavcodec/Makefile
- @@ -741,6 +741,7 @@ OBJS-$(CONFIG_PNG_PARSER) += png_parser.o
- OBJS-$(CONFIG_MPEGAUDIO_PARSER) += mpegaudio_parser.o \
- mpegaudiodecheader.o mpegaudiodata.o
- OBJS-$(CONFIG_MPEGVIDEO_PARSER) += mpegvideo_parser.o \
- + dvd_nav_parser.o \
- mpeg12.o mpeg12data.o
- OBJS-$(CONFIG_PNM_PARSER) += pnm_parser.o pnm.o
- OBJS-$(CONFIG_RV30_PARSER) += rv34_parser.o
- diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c
- index 584446f..1eaf2d3 100644
- --- a/libavcodec/allcodecs.c
- +++ b/libavcodec/allcodecs.c
- @@ -515,6 +515,7 @@ void avcodec_register_all(void)
- REGISTER_PARSER(DNXHD, dnxhd);
- REGISTER_PARSER(DVBSUB, dvbsub);
- REGISTER_PARSER(DVDSUB, dvdsub);
- + REGISTER_PARSER(DVD_NAV, dvd_nav);
- REGISTER_PARSER(FLAC, flac);
- REGISTER_PARSER(GSM, gsm);
- REGISTER_PARSER(H261, h261);
- diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
- index f809e3d..1e08271 100644
- --- a/libavcodec/avcodec.h
- +++ b/libavcodec/avcodec.h
- @@ -483,6 +483,8 @@ enum AVCodecID {
- AV_CODEC_ID_IDF = MKBETAG( 0 ,'I','D','F'),
- AV_CODEC_ID_OTF = MKBETAG( 0 ,'O','T','F'),
- AV_CODEC_ID_SMPTE_KLV = MKBETAG('K','L','V','A'),
- + AV_CODEC_ID_DVD_NAV = MKBETAG('D','N','A','V'),
- +
- AV_CODEC_ID_PROBE = 0x19000, ///< codec_id is not known (like AV_CODEC_ID_NONE) but lavf should attempt to identify it
- diff --git a/libavcodec/codec_desc.c b/libavcodec/codec_desc.c
- index 440e9d9..32db185 100644
- --- a/libavcodec/codec_desc.c
- +++ b/libavcodec/codec_desc.c
- @@ -2523,6 +2523,12 @@ static const AVCodecDescriptor codec_descriptors[] = {
- .name = "klv",
- .long_name = NULL_IF_CONFIG_SMALL("SMPTE 336M Key-Length-Value (KLV) metadata"),
- },
- + {
- + .id = AV_CODEC_ID_DVD_NAV,
- + .type = AVMEDIA_TYPE_DATA,
- + .name = "dvd_nav_packet",
- + .long_name = NULL_IF_CONFIG_SMALL("DVD Nav packet"),
- + },
- };
- diff --git a/libavcodec/dvd_nav_parser.c b/libavcodec/dvd_nav_parser.c
- new file mode 100644
- index 0000000..21deb45
- --- /dev/null
- +++ b/libavcodec/dvd_nav_parser.c
- @@ -0,0 +1,85 @@
- +/*
- + * DVD navigation block parser for FFmpeg
- + * Copyright (c) 2013 The ffmpeg Project
- + *
- + * This file is part of FFmpeg.
- + *
- + * FFmpeg is free software; you can redistribute it and/or
- + * modify it under the terms of the GNU Lesser General Public
- + * License as published by the Free Software Foundation; either
- + * version 2.1 of the License, or (at your option) any later version.
- + *
- + * FFmpeg is distributed in the hope that it will be useful,
- + * but WITHOUT ANY WARRANTY; without even the implied warranty of
- + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- + * Lesser General Public License for more details.
- + *
- + * You should have received a copy of the GNU Lesser General Public
- + * License along with FFmpeg; if not, write to the Free Software
- + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- + */
- +#include "avcodec.h"
- +#include "dsputil.h"
- +#include "get_bits.h"
- +#include "parser.h"
- +
- +/* parser definition */
- +typedef struct DVDNavParseContext {
- + ParseContext pc;
- +} DVDNavParseContext;
- +
- +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 next = END_NOT_FOUND;
- + int blockOK = 1;
- +
- + s->pict_type = AV_PICTURE_TYPE_NONE;
- +
- + avctx->time_base.num = 1;
- + avctx->time_base.den = 90000;
- +
- + switch(buf[0])
- + {
- + case 0x00:
- + {
- + /* PCI */
- + uint32_t startpts = AV_RB32(&buf[0x0D]);
- + uint32_t endpts = AV_RB32(&buf[0x11]);
- + s->pts = (int64_t)startpts;
- + s->duration = endpts - startpts;
- + }
- + break;
- +
- + case 0x01:
- + {
- + /* DSI */
- + next = buf_size;
- + }
- + break;
- +
- + default:
- + blockOK = 0;
- + break;
- + }
- +
- + if (!blockOK || ff_combine_frame(pc, next, &buf, &buf_size) < 0) {
- + *poutbuf = NULL;
- + *poutbuf_size = 0;
- + return buf_size;
- + }
- +
- + *poutbuf = buf;
- + *poutbuf_size = buf_size;
- + return next;
- +}
- +
- +AVCodecParser ff_dvd_nav_parser = {
- + .codec_ids = { AV_CODEC_ID_DVD_NAV },
- + .priv_data_size = sizeof(DVDNavParseContext),
- + .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));
- + } else {
- + avio_skip(s->pb, len);
- + goto redo;
- + }
- }
- if (startcode == PROGRAM_STREAM_MAP) {
- mpegps_psm_parse(m, s->pb);
- @@ -271,7 +281,9 @@ static int mpegps_read_pes_header(AVFormatContext *s,
- /* find matching stream */
- if (!((startcode >= 0x1c0 && startcode <= 0x1df) ||
- (startcode >= 0x1e0 && startcode <= 0x1ef) ||
- - (startcode == 0x1bd) || (startcode == 0x1fd)))
- + (startcode == 0x1bd) ||
- + (startcode == PRIVATE_STREAM_2) ||
- + (startcode == 0x1fd)))
- goto redo;
- if (ppos) {
- *ppos = avio_tell(s->pb) - 4;
- @@ -279,6 +291,8 @@ static int mpegps_read_pes_header(AVFormatContext *s,
- len = avio_rb16(s->pb);
- pts =
- dts = AV_NOPTS_VALUE;
- + if (startcode != PRIVATE_STREAM_2)
- + {
- /* stuffing */
- for(;;) {
- if (len < 1)
- @@ -352,6 +366,7 @@ static int mpegps_read_pes_header(AVFormatContext *s,
- }
- else if( c!= 0xf )
- goto redo;
- + }
- if (startcode == PRIVATE_STREAM_1) {
- startcode = avio_r8(s->pb);
- @@ -448,6 +463,9 @@ static int mpegps_read_packet(AVFormatContext *s,
- else
- request_probe= 1;
- type = AVMEDIA_TYPE_VIDEO;
- + } else if (startcode == PRIVATE_STREAM_2) {
- + type = AVMEDIA_TYPE_DATA;
- + codec_id = AV_CODEC_ID_DVD_NAV;
- } else if (startcode >= 0x1c0 && startcode <= 0x1df) {
- type = AVMEDIA_TYPE_AUDIO;
- codec_id = m->sofdec > 0 ? AV_CODEC_ID_ADPCM_ADX : AV_CODEC_ID_MP2;
- -- 1.7.9.5
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement