Ticket #11579: 0001-Add-passing-of-DVD-NAV-blocks-to-ffmpeg.patch
File 0001-Add-passing-of-DVD-NAV-blocks-to-ffmpeg.patch, 18.0 KB (added by , 11 years ago) |
---|
-
mythtv/external/FFmpeg/libavcodec/Makefile
From fed4ad551d01bfdbded86394389d08705372a977 Mon Sep 17 00:00:00 2001 From: Richard <peper03@yahoo.com> Date: Thu, 4 Apr 2013 23:09:00 +0200 Subject: [PATCH 1/4] Add passing of DVD NAV blocks to ffmpeg --- mythtv/external/FFmpeg/libavcodec/Makefile | 1 + mythtv/external/FFmpeg/libavcodec/allcodecs.c | 1 + mythtv/external/FFmpeg/libavcodec/avcodec.h | 1 + mythtv/external/FFmpeg/libavcodec/codec_desc.c | 6 + mythtv/external/FFmpeg/libavcodec/dvd_nav_parser.c | 116 +++++++++++ mythtv/external/FFmpeg/libavcodec/utils-mythtv.c | 2 + mythtv/external/FFmpeg/libavformat/mpeg.c | 219 +++++++++++++------- 7 files changed, 272 insertions(+), 74 deletions(-) create mode 100644 mythtv/external/FFmpeg/libavcodec/dvd_nav_parser.c diff --git a/mythtv/external/FFmpeg/libavcodec/Makefile b/mythtv/external/FFmpeg/libavcodec/Makefile index edab72c..7e050ff 100644
a b OBJS-$(CONFIG_PNG_PARSER) += png_parser.o 742 742 OBJS-$(CONFIG_MPEGAUDIO_PARSER) += mpegaudio_parser.o \ 743 743 mpegaudiodecheader.o mpegaudiodata.o 744 744 OBJS-$(CONFIG_MPEGVIDEO_PARSER) += mpegvideo_parser.o \ 745 dvd_nav_parser.o \ 745 746 mpeg12.o mpeg12data.o 746 747 OBJS-$(CONFIG_PNM_PARSER) += pnm_parser.o pnm.o 747 748 OBJS-$(CONFIG_RV30_PARSER) += rv34_parser.o -
mythtv/external/FFmpeg/libavcodec/allcodecs.c
diff --git a/mythtv/external/FFmpeg/libavcodec/allcodecs.c b/mythtv/external/FFmpeg/libavcodec/allcodecs.c index 584446f..1eaf2d3 100644
a b void avcodec_register_all(void) 515 515 REGISTER_PARSER(DNXHD, dnxhd); 516 516 REGISTER_PARSER(DVBSUB, dvbsub); 517 517 REGISTER_PARSER(DVDSUB, dvdsub); 518 REGISTER_PARSER(DVD_NAV, dvd_nav); 518 519 REGISTER_PARSER(FLAC, flac); 519 520 REGISTER_PARSER(GSM, gsm); 520 521 REGISTER_PARSER(H261, h261); -
mythtv/external/FFmpeg/libavcodec/avcodec.h
diff --git a/mythtv/external/FFmpeg/libavcodec/avcodec.h b/mythtv/external/FFmpeg/libavcodec/avcodec.h index f828f88..9889866 100644
a b enum AVCodecID { 481 481 482 482 /* DSMCC codec */ 483 483 AV_CODEC_ID_DSMCC_B, 484 AV_CODEC_ID_DVD_NAV = MKBETAG('D','N','A','V'), 484 485 485 486 /* other specific kind of codecs (generally used for attachments) */ 486 487 AV_CODEC_ID_FIRST_UNKNOWN = 0x18000, ///< A dummy ID pointing at the start of various fake codecs. -
mythtv/external/FFmpeg/libavcodec/codec_desc.c
diff --git a/mythtv/external/FFmpeg/libavcodec/codec_desc.c b/mythtv/external/FFmpeg/libavcodec/codec_desc.c index 673f971..ded09c9 100644
a b static const AVCodecDescriptor codec_descriptors[] = { 2525 2525 .name = "klv", 2526 2526 .long_name = NULL_IF_CONFIG_SMALL("SMPTE 336M Key-Length-Value (KLV) metadata"), 2527 2527 }, 2528 { 2529 .id = AV_CODEC_ID_DVD_NAV, 2530 .type = AVMEDIA_TYPE_DATA, 2531 .name = "dvd_nav_packet", 2532 .long_name = NULL_IF_CONFIG_SMALL("DVD Nav packet"), 2533 }, 2528 2534 2529 2535 }; 2530 2536 -
new file mythtv/external/FFmpeg/libavcodec/dvd_nav_parser.c
diff --git a/mythtv/external/FFmpeg/libavcodec/dvd_nav_parser.c b/mythtv/external/FFmpeg/libavcodec/dvd_nav_parser.c new file mode 100644 index 0000000..4b03e39
- + 1 /* 2 * DVD navigation block parser for FFmpeg 3 * Copyright (c) 2013 The FFmpeg Project 4 * 5 * This file is part of FFmpeg. 6 * 7 * FFmpeg is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU Lesser General Public 9 * License as published by the Free Software Foundation; either 10 * version 2.1 of the License, or (at your option) any later version. 11 * 12 * FFmpeg is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * Lesser General Public License for more details. 16 * 17 * You should have received a copy of the GNU Lesser General Public 18 * License along with FFmpeg; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 20 */ 21 #include "avcodec.h" 22 #include "dsputil.h" 23 #include "get_bits.h" 24 #include "parser.h" 25 26 #define PCI_SIZE 980 27 #define DSI_SIZE 1018 28 29 /* parser definition */ 30 typedef struct DVDNavParseContext { 31 uint32_t lba; 32 uint8_t buffer[PCI_SIZE+DSI_SIZE]; 33 int copied; 34 } DVDNavParseContext; 35 36 static av_cold int dvd_nav_parse_init(AVCodecParserContext *s) 37 { 38 DVDNavParseContext *pc = s->priv_data; 39 40 pc->lba = 0xFFFFFFFF; 41 pc->copied = 0; 42 return 0; 43 } 44 45 static int dvd_nav_parse(AVCodecParserContext *s, 46 AVCodecContext *avctx, 47 const uint8_t **poutbuf, int *poutbuf_size, 48 const uint8_t *buf, int buf_size) 49 { 50 DVDNavParseContext *pc1 = s->priv_data; 51 int lastPacket = 0; 52 int valid = 0; 53 54 s->pict_type = AV_PICTURE_TYPE_NONE; 55 56 avctx->time_base.num = 1; 57 avctx->time_base.den = 90000; 58 59 if (buf && buf_size) { 60 switch(buf[0]) { 61 case 0x00: 62 if (buf_size == PCI_SIZE) { 63 /* PCI */ 64 uint32_t lba = AV_RB32(&buf[0x01]); 65 uint32_t startpts = AV_RB32(&buf[0x0D]); 66 uint32_t endpts = AV_RB32(&buf[0x11]); 67 68 if (endpts > startpts) { 69 pc1->lba = lba; 70 s->pts = (int64_t)startpts; 71 s->duration = endpts - startpts; 72 73 memcpy(pc1->buffer, buf, PCI_SIZE); 74 pc1->copied = PCI_SIZE; 75 valid = 1; 76 } 77 } 78 break; 79 80 case 0x01: 81 if ((buf_size == DSI_SIZE) && (pc1->copied == PCI_SIZE)) { 82 /* DSI */ 83 uint32_t lba = AV_RB32(&buf[0x05]); 84 85 if (lba == pc1->lba) { 86 memcpy(pc1->buffer + pc1->copied, buf, DSI_SIZE); 87 lastPacket = 1; 88 valid = 1; 89 } 90 } 91 break; 92 } 93 } 94 95 if (!valid || lastPacket) { 96 pc1->copied = 0; 97 pc1->lba = 0xFFFFFFFF; 98 } 99 100 if (lastPacket) { 101 *poutbuf = pc1->buffer; 102 *poutbuf_size = sizeof(pc1->buffer); 103 } else { 104 *poutbuf = NULL; 105 *poutbuf_size = 0; 106 } 107 108 return buf_size; 109 } 110 111 AVCodecParser ff_dvd_nav_parser = { 112 .codec_ids = { AV_CODEC_ID_DVD_NAV }, 113 .priv_data_size = sizeof(DVDNavParseContext), 114 .parser_init = dvd_nav_parse_init, 115 .parser_parse = dvd_nav_parse, 116 }; -
mythtv/external/FFmpeg/libavcodec/utils-mythtv.c
diff --git a/mythtv/external/FFmpeg/libavcodec/utils-mythtv.c b/mythtv/external/FFmpeg/libavcodec/utils-mythtv.c index b578c6d..694d713 100644
a b const char *ff_codec_id_string(enum CodecID codec_id) 212 212 213 213 case AV_CODEC_ID_DSMCC_B: return "DSMCC_B"; 214 214 215 case AV_CODEC_ID_DVD_NAV: return "DVD NAV"; 216 215 217 case AV_CODEC_ID_MPEG2TS: return "MPEG2TS"; 216 218 217 219 /* Attachment codecs */ -
mythtv/external/FFmpeg/libavformat/mpeg.c
diff --git a/mythtv/external/FFmpeg/libavformat/mpeg.c b/mythtv/external/FFmpeg/libavformat/mpeg.c index 782dcca..d70ab83 100644
a b 30 30 31 31 #undef NDEBUG 32 32 #include <assert.h> 33 #include "libavutil/avassert.h" 33 34 34 35 /*********************************************/ 35 36 /* demux code */ … … typedef struct MpegDemuxContext { 112 113 AVFormatContext *sub_ctx; 113 114 FFDemuxSubtitlesQueue q; 114 115 #endif 116 int dvd; 115 117 } MpegDemuxContext; 116 118 117 119 static int mpegps_read_header(AVFormatContext *s) … … static int mpegps_read_pes_header(AVFormatContext *s, 247 249 goto redo; 248 250 } 249 251 if (startcode == PRIVATE_STREAM_2) { 250 len = avio_rb16(s->pb);251 252 if (!m->sofdec) { 252 while (len-- >= 6) { 253 if (avio_r8(s->pb) == 'S') { 254 uint8_t buf[5]; 255 avio_read(s->pb, buf, sizeof(buf)); 256 m->sofdec = !memcmp(buf, "ofdec", 5); 257 len -= sizeof(buf); 258 break; 253 /* Need to detect whether this from a DVD or a 'Sofdec' stream */ 254 int len = avio_rb16(s->pb); 255 int bytesread = 0; 256 uint8_t *ps2buf = av_malloc(len); 257 258 if (ps2buf) { 259 bytesread = avio_read(s->pb, ps2buf, len); 260 261 if (bytesread != len) { 262 avio_skip(s->pb, len - bytesread); 263 } else { 264 uint8_t *p = 0; 265 if (len >= 6) 266 p = memchr(ps2buf, 'S', len - 5); 267 268 if (p) 269 m->sofdec = !memcmp(p+1, "ofdec", 5); 270 271 m->sofdec -= !m->sofdec; 272 273 if (m->sofdec < 0) { 274 if (len == 980 && ps2buf[0] == 0) { 275 /* PCI structure? */ 276 uint32_t startpts = AV_RB32(ps2buf + 0x0d); 277 uint32_t endpts = AV_RB32(ps2buf + 0x11); 278 uint8_t hours = ((ps2buf[0x19] >> 4) * 10) + (ps2buf[0x19] & 0x0f); 279 uint8_t mins = ((ps2buf[0x1a] >> 4) * 10) + (ps2buf[0x1a] & 0x0f); 280 uint8_t secs = ((ps2buf[0x1b] >> 4) * 10) + (ps2buf[0x1b] & 0x0f); 281 282 m->dvd = (hours <= 23 && 283 mins <= 59 && 284 secs <= 59 && 285 (ps2buf[0x19] & 0x0f) < 10 && 286 (ps2buf[0x1a] & 0x0f) < 10 && 287 (ps2buf[0x1b] & 0x0f) < 10 && 288 endpts >= startpts); 289 } else if (len == 1018 && ps2buf[0] == 1) { 290 /* DSI structure? */ 291 uint8_t hours = ((ps2buf[0x1d] >> 4) * 10) + (ps2buf[0x1d] & 0x0f); 292 uint8_t mins = ((ps2buf[0x1e] >> 4) * 10) + (ps2buf[0x1e] & 0x0f); 293 uint8_t secs = ((ps2buf[0x1f] >> 4) * 10) + (ps2buf[0x1f] & 0x0f); 294 295 m->dvd = (hours <= 23 && 296 mins <= 59 && 297 secs <= 59 && 298 (ps2buf[0x1d] & 0x0f) < 10 && 299 (ps2buf[0x1e] & 0x0f) < 10 && 300 (ps2buf[0x1f] & 0x0f) < 10); 301 } 302 } 259 303 } 304 305 av_free(ps2buf); 306 307 /* If this isn't a DVD packet or no memory 308 * could be allocated, just ignore it. 309 * If we did, move back to the start of the 310 * packet (plus 'length' field) */ 311 if (!m->dvd || avio_skip(s->pb, -(len + 2)) < 0) { 312 /* Skip back failed. 313 * This packet will be lost but that can't be helped 314 * if we can't skip back 315 */ 316 goto redo; 317 } 318 } else { 319 /* No memory */ 320 avio_skip(s->pb, len); 321 goto redo; 260 322 } 261 m->sofdec -= !m->sofdec; 323 } else if (!m->dvd) { 324 int len = avio_rb16(s->pb); 325 avio_skip(s->pb, len); 326 goto redo; 262 327 } 263 avio_skip(s->pb, len);264 goto redo;265 328 } 266 329 if (startcode == PROGRAM_STREAM_MAP) { 267 330 mpegps_psm_parse(m, s->pb); … … static int mpegps_read_pes_header(AVFormatContext *s, 271 334 /* find matching stream */ 272 335 if (!((startcode >= 0x1c0 && startcode <= 0x1df) || 273 336 (startcode >= 0x1e0 && startcode <= 0x1ef) || 274 (startcode == 0x1bd) || (startcode == 0x1fd))) 337 (startcode == 0x1bd) || 338 (startcode == PRIVATE_STREAM_2) || 339 (startcode == 0x1fd))) 275 340 goto redo; 276 341 if (ppos) { 277 342 *ppos = avio_tell(s->pb) - 4; … … static int mpegps_read_pes_header(AVFormatContext *s, 279 344 len = avio_rb16(s->pb); 280 345 pts = 281 346 dts = AV_NOPTS_VALUE; 282 /* stuffing */ 283 for(;;) { 284 if (len < 1) 285 goto error_redo; 286 c = avio_r8(s->pb); 287 len--; 288 /* XXX: for mpeg1, should test only bit 7 */ 289 if (c != 0xff) 290 break; 291 } 292 if ((c & 0xc0) == 0x40) { 293 /* buffer scale & size */ 294 avio_r8(s->pb); 295 c = avio_r8(s->pb); 296 len -= 2; 297 } 298 if ((c & 0xe0) == 0x20) { 299 dts = pts = get_pts(s->pb, c); 300 len -= 4; 301 if (c & 0x10){ 302 dts = get_pts(s->pb, -1); 303 len -= 5; 347 if (startcode != PRIVATE_STREAM_2) 348 { 349 /* stuffing */ 350 for(;;) { 351 if (len < 1) 352 goto error_redo; 353 c = avio_r8(s->pb); 354 len--; 355 /* XXX: for mpeg1, should test only bit 7 */ 356 if (c != 0xff) 357 break; 304 358 } 305 } else if ((c & 0xc0) == 0x80) { 306 /* mpeg 2 PES */ 307 flags = avio_r8(s->pb); 308 header_len = avio_r8(s->pb); 309 len -= 2; 310 if (header_len > len) 311 goto error_redo; 312 len -= header_len; 313 if (flags & 0x80) { 314 dts = pts = get_pts(s->pb, -1); 315 header_len -= 5; 316 if (flags & 0x40) { 359 if ((c & 0xc0) == 0x40) { 360 /* buffer scale & size */ 361 avio_r8(s->pb); 362 c = avio_r8(s->pb); 363 len -= 2; 364 } 365 if ((c & 0xe0) == 0x20) { 366 dts = pts = get_pts(s->pb, c); 367 len -= 4; 368 if (c & 0x10){ 317 369 dts = get_pts(s->pb, -1); 370 len -= 5; 371 } 372 } else if ((c & 0xc0) == 0x80) { 373 /* mpeg 2 PES */ 374 flags = avio_r8(s->pb); 375 header_len = avio_r8(s->pb); 376 len -= 2; 377 if (header_len > len) 378 goto error_redo; 379 len -= header_len; 380 if (flags & 0x80) { 381 dts = pts = get_pts(s->pb, -1); 318 382 header_len -= 5; 383 if (flags & 0x40) { 384 dts = get_pts(s->pb, -1); 385 header_len -= 5; 386 } 319 387 } 320 } 321 if (flags & 0x3f && header_len == 0){ 322 flags &= 0xC0; 323 av_log(s, AV_LOG_WARNING, "Further flags set but no bytes left\n"); 324 } 325 if (flags & 0x01) { /* PES extension */ 326 pes_ext = avio_r8(s->pb); 327 header_len--; 328 /* Skip PES private data, program packet sequence counter and P-STD buffer */ 329 skip = (pes_ext >> 4) & 0xb; 330 skip += skip & 0x9; 331 if (pes_ext & 0x40 || skip > header_len){ 332 av_log(s, AV_LOG_WARNING, "pes_ext %X is invalid\n", pes_ext); 333 pes_ext=skip=0; 388 if (flags & 0x3f && header_len == 0){ 389 flags &= 0xC0; 390 av_log(s, AV_LOG_WARNING, "Further flags set but no bytes left\n"); 334 391 } 335 avio_skip(s->pb, skip); 336 header_len -= skip; 337 338 if (pes_ext & 0x01) { /* PES extension 2 */ 339 ext2_len = avio_r8(s->pb); 392 if (flags & 0x01) { /* PES extension */ 393 pes_ext = avio_r8(s->pb); 340 394 header_len--; 341 if ((ext2_len & 0x7f) > 0) { 342 id_ext = avio_r8(s->pb); 343 if ((id_ext & 0x80) == 0) 344 startcode = ((startcode & 0xff) << 8) | id_ext; 395 /* Skip PES private data, program packet sequence counter and P-STD buffer */ 396 skip = (pes_ext >> 4) & 0xb; 397 skip += skip & 0x9; 398 if (pes_ext & 0x40 || skip > header_len){ 399 av_log(s, AV_LOG_WARNING, "pes_ext %X is invalid\n", pes_ext); 400 pes_ext=skip=0; 401 } 402 avio_skip(s->pb, skip); 403 header_len -= skip; 404 405 if (pes_ext & 0x01) { /* PES extension 2 */ 406 ext2_len = avio_r8(s->pb); 345 407 header_len--; 408 if ((ext2_len & 0x7f) > 0) { 409 id_ext = avio_r8(s->pb); 410 if ((id_ext & 0x80) == 0) 411 startcode = ((startcode & 0xff) << 8) | id_ext; 412 header_len--; 413 } 346 414 } 347 415 } 416 if(header_len < 0) 417 goto error_redo; 418 avio_skip(s->pb, header_len); 348 419 } 349 if(header_len < 0) 350 goto error_redo; 351 avio_skip(s->pb, header_len); 420 else if( c!= 0xf ) 421 goto redo; 352 422 } 353 else if( c!= 0xf )354 goto redo;355 423 356 424 if (startcode == PRIVATE_STREAM_1) { 357 425 startcode = avio_r8(s->pb); … … static int mpegps_read_packet(AVFormatContext *s, 451 519 else 452 520 request_probe= 1; 453 521 type = AVMEDIA_TYPE_VIDEO; 522 } else if (startcode == PRIVATE_STREAM_2) { 523 type = AVMEDIA_TYPE_DATA; 524 codec_id = AV_CODEC_ID_DVD_NAV; 454 525 } else if (startcode >= 0x1c0 && startcode <= 0x1df) { 455 526 type = AVMEDIA_TYPE_AUDIO; 456 527 codec_id = m->sofdec > 0 ? AV_CODEC_ID_ADPCM_ADX : AV_CODEC_ID_MP2;