| OLD | NEW |
| 1 /* | 1 /* |
| 2 * MPEG2 transport stream (aka DVB) muxer | 2 * MPEG2 transport stream (aka DVB) muxer |
| 3 * Copyright (c) 2003 Fabrice Bellard | 3 * Copyright (c) 2003 Fabrice Bellard |
| 4 * | 4 * |
| 5 * This file is part of FFmpeg. | 5 * This file is part of FFmpeg. |
| 6 * | 6 * |
| 7 * FFmpeg is free software; you can redistribute it and/or | 7 * FFmpeg is free software; you can redistribute it and/or |
| 8 * modify it under the terms of the GNU Lesser General Public | 8 * modify it under the terms of the GNU Lesser General Public |
| 9 * License as published by the Free Software Foundation; either | 9 * License as published by the Free Software Foundation; either |
| 10 * version 2.1 of the License, or (at your option) any later version. | 10 * version 2.1 of the License, or (at your option) any later version. |
| 11 * | 11 * |
| 12 * FFmpeg is distributed in the hope that it will be useful, | 12 * FFmpeg is distributed in the hope that it will be useful, |
| 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of | 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| 15 * Lesser General Public License for more details. | 15 * Lesser General Public License for more details. |
| 16 * | 16 * |
| 17 * You should have received a copy of the GNU Lesser General Public | 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 | 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 | 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
| 20 */ | 20 */ |
| 21 | 21 |
| 22 #include "libavutil/bswap.h" | 22 #include "libavutil/bswap.h" |
| 23 #include "libavutil/crc.h" | 23 #include "libavutil/crc.h" |
| 24 #include "libavcodec/mpegvideo.h" | 24 #include "libavcodec/mpegvideo.h" |
| 25 #include "avformat.h" | 25 #include "avformat.h" |
| 26 #include "mpegts.h" | 26 #include "mpegts.h" |
| 27 #include "adts.h" |
| 27 | 28 |
| 28 /* write DVB SI sections */ | 29 /* write DVB SI sections */ |
| 29 | 30 |
| 30 /*********************************************/ | 31 /*********************************************/ |
| 31 /* mpegts section writer */ | 32 /* mpegts section writer */ |
| 32 | 33 |
| 33 typedef struct MpegTSSection { | 34 typedef struct MpegTSSection { |
| 34 int pid; | 35 int pid; |
| 35 int cc; | 36 int cc; |
| 36 void (*write_packet)(struct MpegTSSection *s, const uint8_t *packet); | 37 void (*write_packet)(struct MpegTSSection *s, const uint8_t *packet); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 52 MpegTSSection sdt; /* MPEG2 sdt table context */ | 53 MpegTSSection sdt; /* MPEG2 sdt table context */ |
| 53 MpegTSService **services; | 54 MpegTSService **services; |
| 54 int sdt_packet_count; | 55 int sdt_packet_count; |
| 55 int sdt_packet_period; | 56 int sdt_packet_period; |
| 56 int pat_packet_count; | 57 int pat_packet_count; |
| 57 int pat_packet_period; | 58 int pat_packet_period; |
| 58 int nb_services; | 59 int nb_services; |
| 59 int onid; | 60 int onid; |
| 60 int tsid; | 61 int tsid; |
| 61 uint64_t cur_pcr; | 62 uint64_t cur_pcr; |
| 62 int mux_rate; | 63 int mux_rate; ///< set to 1 when VBR |
| 63 } MpegTSWrite; | 64 } MpegTSWrite; |
| 64 | 65 |
| 65 /* NOTE: 4 bytes must be left at the end for the crc32 */ | 66 /* NOTE: 4 bytes must be left at the end for the crc32 */ |
| 66 static void mpegts_write_section(MpegTSSection *s, uint8_t *buf, int len) | 67 static void mpegts_write_section(MpegTSSection *s, uint8_t *buf, int len) |
| 67 { | 68 { |
| 68 MpegTSWrite *ts = ((AVFormatContext*)s->opaque)->priv_data; | 69 MpegTSWrite *ts = ((AVFormatContext*)s->opaque)->priv_data; |
| 69 unsigned int crc; | 70 unsigned int crc; |
| 70 unsigned char packet[TS_PACKET_SIZE]; | 71 unsigned char packet[TS_PACKET_SIZE]; |
| 71 const unsigned char *buf_ptr; | 72 const unsigned char *buf_ptr; |
| 72 unsigned char *q; | 73 unsigned char *q; |
| 73 int first, b, len1, left; | 74 int first, b, len1, left; |
| 74 | 75 |
| 75 crc = bswap_32(av_crc(av_crc_get_table(AV_CRC_32_IEEE), -1, buf, len - 4)); | 76 crc = bswap_32(av_crc(av_crc_get_table(AV_CRC_32_IEEE), -1, buf, len - 4)); |
| 76 buf[len - 4] = (crc >> 24) & 0xff; | 77 buf[len - 4] = (crc >> 24) & 0xff; |
| 77 buf[len - 3] = (crc >> 16) & 0xff; | 78 buf[len - 3] = (crc >> 16) & 0xff; |
| 78 buf[len - 2] = (crc >> 8) & 0xff; | 79 buf[len - 2] = (crc >> 8) & 0xff; |
| 79 buf[len - 1] = (crc) & 0xff; | 80 buf[len - 1] = (crc) & 0xff; |
| 80 | 81 |
| 81 /* send each packet */ | 82 /* send each packet */ |
| 82 buf_ptr = buf; | 83 buf_ptr = buf; |
| 83 while (len > 0) { | 84 while (len > 0) { |
| 84 first = (buf == buf_ptr); | 85 first = (buf == buf_ptr); |
| 85 q = packet; | 86 q = packet; |
| 86 *q++ = 0x47; | 87 *q++ = 0x47; |
| 87 b = (s->pid >> 8); | 88 b = (s->pid >> 8); |
| 88 if (first) | 89 if (first) |
| 89 b |= 0x40; | 90 b |= 0x40; |
| 90 *q++ = b; | 91 *q++ = b; |
| 91 *q++ = s->pid; | 92 *q++ = s->pid; |
| 93 s->cc = (s->cc + 1) & 0xf; |
| 92 *q++ = 0x10 | s->cc; | 94 *q++ = 0x10 | s->cc; |
| 93 s->cc = (s->cc + 1) & 0xf; | |
| 94 if (first) | 95 if (first) |
| 95 *q++ = 0; /* 0 offset */ | 96 *q++ = 0; /* 0 offset */ |
| 96 len1 = TS_PACKET_SIZE - (q - packet); | 97 len1 = TS_PACKET_SIZE - (q - packet); |
| 97 if (len1 > len) | 98 if (len1 > len) |
| 98 len1 = len; | 99 len1 = len; |
| 99 memcpy(q, buf_ptr, len1); | 100 memcpy(q, buf_ptr, len1); |
| 100 q += len1; | 101 q += len1; |
| 101 /* add known padding data */ | 102 /* add known padding data */ |
| 102 left = TS_PACKET_SIZE - (q - packet); | 103 left = TS_PACKET_SIZE - (q - packet); |
| 103 if (left > 0) | 104 if (left > 0) |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 170 | 171 |
| 171 typedef struct MpegTSWriteStream { | 172 typedef struct MpegTSWriteStream { |
| 172 struct MpegTSService *service; | 173 struct MpegTSService *service; |
| 173 int pid; /* stream associated pid */ | 174 int pid; /* stream associated pid */ |
| 174 int cc; | 175 int cc; |
| 175 int payload_index; | 176 int payload_index; |
| 176 int first_pts_check; ///< first pts check needed | 177 int first_pts_check; ///< first pts check needed |
| 177 int64_t payload_pts; | 178 int64_t payload_pts; |
| 178 int64_t payload_dts; | 179 int64_t payload_dts; |
| 179 uint8_t payload[DEFAULT_PES_PAYLOAD_SIZE]; | 180 uint8_t payload[DEFAULT_PES_PAYLOAD_SIZE]; |
| 181 ADTSContext *adts; |
| 180 } MpegTSWriteStream; | 182 } MpegTSWriteStream; |
| 181 | 183 |
| 182 static void mpegts_write_pat(AVFormatContext *s) | 184 static void mpegts_write_pat(AVFormatContext *s) |
| 183 { | 185 { |
| 184 MpegTSWrite *ts = s->priv_data; | 186 MpegTSWrite *ts = s->priv_data; |
| 185 MpegTSService *service; | 187 MpegTSService *service; |
| 186 uint8_t data[1012], *q; | 188 uint8_t data[1012], *q; |
| 187 int i; | 189 int i; |
| 188 | 190 |
| 189 q = data; | 191 q = data; |
| (...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 375 { | 377 { |
| 376 AVFormatContext *ctx = s->opaque; | 378 AVFormatContext *ctx = s->opaque; |
| 377 put_buffer(ctx->pb, packet, TS_PACKET_SIZE); | 379 put_buffer(ctx->pb, packet, TS_PACKET_SIZE); |
| 378 } | 380 } |
| 379 | 381 |
| 380 static int mpegts_write_header(AVFormatContext *s) | 382 static int mpegts_write_header(AVFormatContext *s) |
| 381 { | 383 { |
| 382 MpegTSWrite *ts = s->priv_data; | 384 MpegTSWrite *ts = s->priv_data; |
| 383 MpegTSWriteStream *ts_st; | 385 MpegTSWriteStream *ts_st; |
| 384 MpegTSService *service; | 386 MpegTSService *service; |
| 385 AVStream *st; | 387 AVStream *st, *pcr_st = NULL; |
| 386 AVMetadataTag *title; | 388 AVMetadataTag *title; |
| 387 int i, total_bit_rate; | 389 int i; |
| 388 const char *service_name; | 390 const char *service_name; |
| 389 uint64_t sdt_size, pat_pmt_size, pos; | |
| 390 | 391 |
| 391 ts->tsid = DEFAULT_TSID; | 392 ts->tsid = DEFAULT_TSID; |
| 392 ts->onid = DEFAULT_ONID; | 393 ts->onid = DEFAULT_ONID; |
| 393 /* allocate a single DVB service */ | 394 /* allocate a single DVB service */ |
| 394 title = av_metadata_get(s->metadata, "title", NULL, 0); | 395 title = av_metadata_get(s->metadata, "title", NULL, 0); |
| 395 service_name = title ? title->value : DEFAULT_SERVICE_NAME; | 396 service_name = title ? title->value : DEFAULT_SERVICE_NAME; |
| 396 service = mpegts_add_service(ts, DEFAULT_SID, | 397 service = mpegts_add_service(ts, DEFAULT_SID, |
| 397 DEFAULT_PROVIDER_NAME, service_name); | 398 DEFAULT_PROVIDER_NAME, service_name); |
| 398 service->pmt.write_packet = section_write_packet; | 399 service->pmt.write_packet = section_write_packet; |
| 399 service->pmt.opaque = s; | 400 service->pmt.opaque = s; |
| 401 service->pmt.cc = 15; |
| 400 | 402 |
| 401 ts->pat.pid = PAT_PID; | 403 ts->pat.pid = PAT_PID; |
| 402 ts->pat.cc = 0; | 404 ts->pat.cc = 15; // Initialize at 15 so that it wraps and be equal to 0 for
the first packet we write |
| 403 ts->pat.write_packet = section_write_packet; | 405 ts->pat.write_packet = section_write_packet; |
| 404 ts->pat.opaque = s; | 406 ts->pat.opaque = s; |
| 405 | 407 |
| 406 ts->sdt.pid = SDT_PID; | 408 ts->sdt.pid = SDT_PID; |
| 407 ts->sdt.cc = 0; | 409 ts->sdt.cc = 15; |
| 408 ts->sdt.write_packet = section_write_packet; | 410 ts->sdt.write_packet = section_write_packet; |
| 409 ts->sdt.opaque = s; | 411 ts->sdt.opaque = s; |
| 410 | 412 |
| 411 /* assign pids to each stream */ | 413 /* assign pids to each stream */ |
| 412 total_bit_rate = 0; | |
| 413 for(i = 0;i < s->nb_streams; i++) { | 414 for(i = 0;i < s->nb_streams; i++) { |
| 414 st = s->streams[i]; | 415 st = s->streams[i]; |
| 415 ts_st = av_mallocz(sizeof(MpegTSWriteStream)); | 416 ts_st = av_mallocz(sizeof(MpegTSWriteStream)); |
| 416 if (!ts_st) | 417 if (!ts_st) |
| 417 goto fail; | 418 goto fail; |
| 418 st->priv_data = ts_st; | 419 st->priv_data = ts_st; |
| 419 ts_st->service = service; | 420 ts_st->service = service; |
| 420 ts_st->pid = DEFAULT_START_PID + i; | 421 ts_st->pid = DEFAULT_START_PID + i; |
| 421 ts_st->payload_pts = AV_NOPTS_VALUE; | 422 ts_st->payload_pts = AV_NOPTS_VALUE; |
| 422 ts_st->payload_dts = AV_NOPTS_VALUE; | 423 ts_st->payload_dts = AV_NOPTS_VALUE; |
| 423 ts_st->first_pts_check = 1; | 424 ts_st->first_pts_check = 1; |
| 425 ts_st->cc = 15; |
| 424 /* update PCR pid by using the first video stream */ | 426 /* update PCR pid by using the first video stream */ |
| 425 if (st->codec->codec_type == CODEC_TYPE_VIDEO && | 427 if (st->codec->codec_type == CODEC_TYPE_VIDEO && |
| 426 service->pcr_pid == 0x1fff) | 428 service->pcr_pid == 0x1fff) { |
| 427 service->pcr_pid = ts_st->pid; | 429 service->pcr_pid = ts_st->pid; |
| 428 if (st->codec->rc_max_rate) | 430 pcr_st = st; |
| 429 total_bit_rate += st->codec->rc_max_rate; | |
| 430 else { | |
| 431 if (!st->codec->bit_rate) { | |
| 432 av_log(s, AV_LOG_WARNING, | |
| 433 "stream %d, bit rate is not set, this will cause problems
\n", | |
| 434 st->index); | |
| 435 } | |
| 436 total_bit_rate += st->codec->bit_rate; | |
| 437 } | 431 } |
| 438 /* PES header size */ | 432 if (st->codec->codec_id == CODEC_ID_AAC && |
| 439 if (st->codec->codec_type == CODEC_TYPE_VIDEO || | 433 st->codec->extradata_size > 0) { |
| 440 st->codec->codec_type == CODEC_TYPE_SUBTITLE) { | 434 ts_st->adts = av_mallocz(sizeof(*ts_st->adts)); |
| 441 /* 1 PES per frame | 435 if (!ts_st->adts) |
| 442 * 19 bytes of PES header | 436 return AVERROR_NOMEM; |
| 443 * on average a half TS-packet (184/2) of padding-overhead every PES
*/ | 437 if (ff_adts_decode_extradata(s, ts_st->adts, st->codec->extradata, |
| 444 total_bit_rate += (19 + 184/2)*8 / av_q2d(st->codec->time_base); | 438 st->codec->extradata_size) < 0) |
| 445 } else { | 439 return -1; |
| 446 /* 1 PES per DEFAULT_PES_PAYLOAD_SIZE bytes of audio data | |
| 447 * 14 bytes of PES header | |
| 448 * on average a half TS-packet (184/2) of padding-overhead every PES
*/ | |
| 449 total_bit_rate += (14 + 184/2) * | |
| 450 st->codec->bit_rate / DEFAULT_PES_PAYLOAD_SIZE; | |
| 451 } | 440 } |
| 452 } | 441 } |
| 453 | 442 |
| 454 /* if no video stream, use the first stream as PCR */ | 443 /* if no video stream, use the first stream as PCR */ |
| 455 if (service->pcr_pid == 0x1fff && s->nb_streams > 0) { | 444 if (service->pcr_pid == 0x1fff && s->nb_streams > 0) { |
| 456 ts_st = s->streams[0]->priv_data; | 445 pcr_st = s->streams[0]; |
| 446 ts_st = pcr_st->priv_data; |
| 457 service->pcr_pid = ts_st->pid; | 447 service->pcr_pid = ts_st->pid; |
| 458 } | 448 } |
| 459 | 449 |
| 460 ts->mux_rate = 1; // avoid div by 0 | 450 ts->mux_rate = s->mux_rate ? s->mux_rate : 1; |
| 461 | 451 |
| 462 /* write info at the start of the file, so that it will be fast to | 452 if (ts->mux_rate > 1) { |
| 463 find them */ | |
| 464 pos = url_ftell(s->pb); | |
| 465 mpegts_write_sdt(s); | |
| 466 sdt_size = url_ftell(s->pb) - pos; | |
| 467 pos = url_ftell(s->pb); | |
| 468 mpegts_write_pat(s); | |
| 469 for(i = 0; i < ts->nb_services; i++) { | |
| 470 mpegts_write_pmt(s, ts->services[i]); | |
| 471 } | |
| 472 pat_pmt_size = url_ftell(s->pb) - pos; | |
| 473 | |
| 474 if (total_bit_rate <= 8 * 1024) | |
| 475 total_bit_rate = 8 * 1024; | |
| 476 | |
| 477 total_bit_rate += | |
| 478 total_bit_rate * 4 / (TS_PACKET_SIZE-4) + /* TS header size */ | |
| 479 1000 * 8 * sdt_size / PAT_RETRANS_TIME + /* SDT size */ | |
| 480 1000 * 8 * pat_pmt_size / SDT_RETRANS_TIME + /* PAT+PMT size */ | |
| 481 1000 * 8 * 8 / PCR_RETRANS_TIME; /* PCR size */ | |
| 482 | |
| 483 if (s->mux_rate) | |
| 484 ts->mux_rate = s->mux_rate; | |
| 485 else | |
| 486 ts->mux_rate = total_bit_rate; | |
| 487 | |
| 488 service->pcr_packet_period = (ts->mux_rate * PCR_RETRANS_TIME) / | 453 service->pcr_packet_period = (ts->mux_rate * PCR_RETRANS_TIME) / |
| 489 (TS_PACKET_SIZE * 8 * 1000); | 454 (TS_PACKET_SIZE * 8 * 1000); |
| 490 ts->sdt_packet_period = (ts->mux_rate * SDT_RETRANS_TIME) / | 455 ts->sdt_packet_period = (ts->mux_rate * SDT_RETRANS_TIME) / |
| 491 (TS_PACKET_SIZE * 8 * 1000); | 456 (TS_PACKET_SIZE * 8 * 1000); |
| 492 ts->pat_packet_period = (ts->mux_rate * PAT_RETRANS_TIME) / | 457 ts->pat_packet_period = (ts->mux_rate * PAT_RETRANS_TIME) / |
| 493 (TS_PACKET_SIZE * 8 * 1000); | 458 (TS_PACKET_SIZE * 8 * 1000); |
| 494 | 459 |
| 460 ts->cur_pcr = av_rescale(s->max_delay, 90000, AV_TIME_BASE); |
| 461 } else { |
| 462 /* Arbitrary values, PAT/PMT could be written on key frames */ |
| 463 ts->sdt_packet_period = 200; |
| 464 ts->pat_packet_period = 40; |
| 465 if (pcr_st->codec->codec_type == CODEC_TYPE_AUDIO) { |
| 466 if (!pcr_st->codec->frame_size) { |
| 467 av_log(s, AV_LOG_WARNING, "frame size not set\n"); |
| 468 service->pcr_packet_period = |
| 469 pcr_st->codec->sample_rate/(10*512); |
| 470 } else { |
| 471 service->pcr_packet_period = |
| 472 pcr_st->codec->sample_rate/(10*pcr_st->codec->frame_size); |
| 473 } |
| 474 } else { |
| 475 // max delta PCR 0.1s |
| 476 service->pcr_packet_period = |
| 477 pcr_st->codec->time_base.den/(10*pcr_st->codec->time_base.num); |
| 478 } |
| 479 } |
| 480 |
| 495 // output a PCR as soon as possible | 481 // output a PCR as soon as possible |
| 496 service->pcr_packet_count = service->pcr_packet_period; | 482 service->pcr_packet_count = service->pcr_packet_period; |
| 483 ts->pat_packet_count = ts->pat_packet_period-1; |
| 484 ts->sdt_packet_count = ts->sdt_packet_period-1; |
| 497 | 485 |
| 498 av_log(s, AV_LOG_DEBUG, | 486 av_log(s, AV_LOG_INFO, |
| 499 "calculated bitrate %d bps, muxrate %d bps, " | 487 "muxrate %d bps, pcr every %d pkts, " |
| 500 "sdt every %d, pat/pmt every %d pkts\n", | 488 "sdt every %d, pat/pmt every %d pkts\n", |
| 501 total_bit_rate, ts->mux_rate, ts->sdt_packet_period, | 489 ts->mux_rate, service->pcr_packet_period, |
| 502 ts->pat_packet_period); | 490 ts->sdt_packet_period, ts->pat_packet_period); |
| 503 | 491 |
| 504 // adjust pcr | |
| 505 ts->cur_pcr /= ts->mux_rate; | |
| 506 | 492 |
| 507 put_flush_packet(s->pb); | 493 put_flush_packet(s->pb); |
| 508 | 494 |
| 509 return 0; | 495 return 0; |
| 510 | 496 |
| 511 fail: | 497 fail: |
| 512 for(i = 0;i < s->nb_streams; i++) { | 498 for(i = 0;i < s->nb_streams; i++) { |
| 513 st = s->streams[i]; | 499 st = s->streams[i]; |
| 514 av_free(st->priv_data); | 500 av_free(st->priv_data); |
| 515 } | 501 } |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 615 int afc_len, stuffing_len; | 601 int afc_len, stuffing_len; |
| 616 int64_t pcr = -1; /* avoid warning */ | 602 int64_t pcr = -1; /* avoid warning */ |
| 617 int64_t delay = av_rescale(s->max_delay, 90000, AV_TIME_BASE); | 603 int64_t delay = av_rescale(s->max_delay, 90000, AV_TIME_BASE); |
| 618 | 604 |
| 619 is_start = 1; | 605 is_start = 1; |
| 620 while (payload_size > 0) { | 606 while (payload_size > 0) { |
| 621 retransmit_si_info(s); | 607 retransmit_si_info(s); |
| 622 | 608 |
| 623 write_pcr = 0; | 609 write_pcr = 0; |
| 624 if (ts_st->pid == ts_st->service->pcr_pid) { | 610 if (ts_st->pid == ts_st->service->pcr_pid) { |
| 625 ts_st->service->pcr_packet_count++; | 611 if (ts->mux_rate > 1 || is_start) // VBR pcr period is based on fram
es |
| 612 ts_st->service->pcr_packet_count++; |
| 626 if (ts_st->service->pcr_packet_count >= | 613 if (ts_st->service->pcr_packet_count >= |
| 627 ts_st->service->pcr_packet_period) { | 614 ts_st->service->pcr_packet_period) { |
| 628 ts_st->service->pcr_packet_count = 0; | 615 ts_st->service->pcr_packet_count = 0; |
| 629 write_pcr = 1; | 616 write_pcr = 1; |
| 630 } | 617 } |
| 631 } | 618 } |
| 632 | 619 |
| 633 if (dts != AV_NOPTS_VALUE && (dts - (int64_t)ts->cur_pcr) > delay) { | 620 if (ts->mux_rate > 1 && dts != AV_NOPTS_VALUE && |
| 621 (dts - (int64_t)ts->cur_pcr) > delay) { |
| 634 /* pcr insert gets priority over null packet insert */ | 622 /* pcr insert gets priority over null packet insert */ |
| 635 if (write_pcr) | 623 if (write_pcr) |
| 636 mpegts_insert_pcr_only(s, st); | 624 mpegts_insert_pcr_only(s, st); |
| 637 else | 625 else |
| 638 mpegts_insert_null_packet(s); | 626 mpegts_insert_null_packet(s); |
| 639 continue; /* recalculate write_pcr and possibly retransmit si_info *
/ | 627 continue; /* recalculate write_pcr and possibly retransmit si_info *
/ |
| 640 } | 628 } |
| 641 | 629 |
| 642 /* prepare packet header */ | 630 /* prepare packet header */ |
| 643 q = buf; | 631 q = buf; |
| 644 *q++ = 0x47; | 632 *q++ = 0x47; |
| 645 val = (ts_st->pid >> 8); | 633 val = (ts_st->pid >> 8); |
| 646 if (is_start) | 634 if (is_start) |
| 647 val |= 0x40; | 635 val |= 0x40; |
| 648 *q++ = val; | 636 *q++ = val; |
| 649 *q++ = ts_st->pid; | 637 *q++ = ts_st->pid; |
| 638 ts_st->cc = (ts_st->cc + 1) & 0xf; |
| 650 *q++ = 0x10 | ts_st->cc | (write_pcr ? 0x20 : 0); | 639 *q++ = 0x10 | ts_st->cc | (write_pcr ? 0x20 : 0); |
| 651 ts_st->cc = (ts_st->cc + 1) & 0xf; | |
| 652 if (write_pcr) { | 640 if (write_pcr) { |
| 653 // add 11, pcr references the last byte of program clock reference b
ase | 641 // add 11, pcr references the last byte of program clock reference b
ase |
| 654 pcr = ts->cur_pcr + (4+7)*8*90000LL / ts->mux_rate; | 642 if (ts->mux_rate > 1) |
| 643 pcr = ts->cur_pcr + (4+7)*8*90000LL / ts->mux_rate; |
| 644 else |
| 645 pcr = dts - delay; |
| 655 if (dts != AV_NOPTS_VALUE && dts < pcr) | 646 if (dts != AV_NOPTS_VALUE && dts < pcr) |
| 656 av_log(s, AV_LOG_WARNING, "dts < pcr, TS is invalid\n"); | 647 av_log(s, AV_LOG_WARNING, "dts < pcr, TS is invalid\n"); |
| 657 *q++ = 7; /* AFC length */ | 648 *q++ = 7; /* AFC length */ |
| 658 *q++ = 0x10; /* flags: PCR present */ | 649 *q++ = 0x10; /* flags: PCR present */ |
| 659 *q++ = pcr >> 25; | 650 *q++ = pcr >> 25; |
| 660 *q++ = pcr >> 17; | 651 *q++ = pcr >> 17; |
| 661 *q++ = pcr >> 9; | 652 *q++ = pcr >> 9; |
| 662 *q++ = pcr >> 1; | 653 *q++ = pcr >> 1; |
| 663 *q++ = (pcr & 1) << 7; | 654 *q++ = (pcr & 1) << 7; |
| 664 *q++ = 0; | 655 *q++ = 0; |
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 781 put_flush_packet(s->pb); | 772 put_flush_packet(s->pb); |
| 782 } | 773 } |
| 783 | 774 |
| 784 static int mpegts_write_packet(AVFormatContext *s, AVPacket *pkt) | 775 static int mpegts_write_packet(AVFormatContext *s, AVPacket *pkt) |
| 785 { | 776 { |
| 786 AVStream *st = s->streams[pkt->stream_index]; | 777 AVStream *st = s->streams[pkt->stream_index]; |
| 787 int size = pkt->size; | 778 int size = pkt->size; |
| 788 uint8_t *buf= pkt->data; | 779 uint8_t *buf= pkt->data; |
| 789 uint8_t *data= NULL; | 780 uint8_t *data= NULL; |
| 790 MpegTSWriteStream *ts_st = st->priv_data; | 781 MpegTSWriteStream *ts_st = st->priv_data; |
| 791 const uint64_t delay = av_rescale(s->max_delay, 90000, AV_TIME_BASE); | 782 const uint64_t delay = av_rescale(s->max_delay, 90000, AV_TIME_BASE)*2; |
| 792 int64_t dts = AV_NOPTS_VALUE, pts = AV_NOPTS_VALUE; | 783 int64_t dts = AV_NOPTS_VALUE, pts = AV_NOPTS_VALUE; |
| 793 | 784 |
| 794 if (pkt->pts != AV_NOPTS_VALUE) | 785 if (pkt->pts != AV_NOPTS_VALUE) |
| 795 pts = pkt->pts + delay; | 786 pts = pkt->pts + delay; |
| 796 if (pkt->dts != AV_NOPTS_VALUE) | 787 if (pkt->dts != AV_NOPTS_VALUE) |
| 797 dts = pkt->dts + delay; | 788 dts = pkt->dts + delay; |
| 798 | 789 |
| 799 if (ts_st->first_pts_check && pts == AV_NOPTS_VALUE) { | 790 if (ts_st->first_pts_check && pts == AV_NOPTS_VALUE) { |
| 800 av_log(s, AV_LOG_ERROR, "first pts value must set\n"); | 791 av_log(s, AV_LOG_ERROR, "first pts value must set\n"); |
| 801 return -1; | 792 return -1; |
| 802 } | 793 } |
| 803 ts_st->first_pts_check = 0; | 794 ts_st->first_pts_check = 0; |
| 804 | 795 |
| 805 if (st->codec->codec_id == CODEC_ID_H264) { | 796 if (st->codec->codec_id == CODEC_ID_H264) { |
| 797 const uint8_t *p = buf, *buf_end = p+size; |
| 798 uint32_t state = -1; |
| 799 |
| 806 if (pkt->size < 5 || AV_RB32(pkt->data) != 0x0000001) { | 800 if (pkt->size < 5 || AV_RB32(pkt->data) != 0x0000001) { |
| 807 av_log(s, AV_LOG_ERROR, "h264 bitstream malformated\n"); | 801 av_log(s, AV_LOG_ERROR, "h264 bitstream malformated, " |
| 802 "no startcode found, use -vbsf h264_mp4toannexb\n"); |
| 808 return -1; | 803 return -1; |
| 809 } | 804 } |
| 810 if (pkt->data[4] != 0x09) { // AUD NAL | 805 |
| 806 do { |
| 807 p = ff_find_start_code(p, buf_end, &state); |
| 808 //av_log(s, AV_LOG_INFO, "nal %d\n", state & 0x1f); |
| 809 } while (p < buf_end && (state & 0x1f) != 9 && |
| 810 (state & 0x1f) != 5 && (state & 0x1f) != 1); |
| 811 |
| 812 if ((state & 0x1f) != 9) { // AUD NAL |
| 811 data = av_malloc(pkt->size+6); | 813 data = av_malloc(pkt->size+6); |
| 812 if (!data) | 814 if (!data) |
| 813 return -1; | 815 return -1; |
| 814 memcpy(data+6, pkt->data, pkt->size); | 816 memcpy(data+6, pkt->data, pkt->size); |
| 815 AV_WB32(data, 0x00000001); | 817 AV_WB32(data, 0x00000001); |
| 816 data[4] = 0x09; | 818 data[4] = 0x09; |
| 817 data[5] = 0xe0; // any slice type | 819 data[5] = 0xe0; // any slice type |
| 818 buf = data; | 820 buf = data; |
| 819 size = pkt->size+6; | 821 size = pkt->size+6; |
| 820 } | 822 } |
| 823 } else if (st->codec->codec_id == CODEC_ID_AAC) { |
| 824 if (pkt->size < 2) |
| 825 return -1; |
| 826 if ((AV_RB16(pkt->data) & 0xfff0) != 0xfff0) { |
| 827 ADTSContext *adts = ts_st->adts; |
| 828 int new_size; |
| 829 if (!adts) { |
| 830 av_log(s, AV_LOG_ERROR, "aac bitstream not in adts format " |
| 831 "and extradata missing\n"); |
| 832 return -1; |
| 833 } |
| 834 new_size = ADTS_HEADER_SIZE+adts->pce_size+pkt->size; |
| 835 if ((unsigned)new_size >= INT_MAX) |
| 836 return -1; |
| 837 data = av_malloc(new_size); |
| 838 if (!data) |
| 839 return AVERROR_NOMEM; |
| 840 ff_adts_write_frame_header(adts, data, pkt->size, adts->pce_size); |
| 841 if (adts->pce_size) { |
| 842 memcpy(data+ADTS_HEADER_SIZE, adts->pce_data, adts->pce_size); |
| 843 adts->pce_size = 0; |
| 844 } |
| 845 memcpy(data+ADTS_HEADER_SIZE+adts->pce_size, pkt->data, pkt->size); |
| 846 buf = data; |
| 847 size = new_size; |
| 848 } |
| 821 } | 849 } |
| 822 | 850 |
| 823 if (st->codec->codec_type != CODEC_TYPE_AUDIO) { | 851 if (st->codec->codec_type != CODEC_TYPE_AUDIO) { |
| 824 // for video and subtitle, write a single pes packet | 852 // for video and subtitle, write a single pes packet |
| 825 mpegts_write_pes(s, st, buf, size, pts, dts); | 853 mpegts_write_pes(s, st, buf, size, pts, dts); |
| 826 av_free(data); | 854 av_free(data); |
| 827 return 0; | 855 return 0; |
| 828 } | 856 } |
| 829 | 857 |
| 830 if (ts_st->payload_index + size > DEFAULT_PES_PAYLOAD_SIZE) { | 858 if (ts_st->payload_index + size > DEFAULT_PES_PAYLOAD_SIZE) { |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 879 NULL_IF_CONFIG_SMALL("MPEG-2 transport stream format"), | 907 NULL_IF_CONFIG_SMALL("MPEG-2 transport stream format"), |
| 880 "video/x-mpegts", | 908 "video/x-mpegts", |
| 881 "ts,m2t", | 909 "ts,m2t", |
| 882 sizeof(MpegTSWrite), | 910 sizeof(MpegTSWrite), |
| 883 CODEC_ID_MP2, | 911 CODEC_ID_MP2, |
| 884 CODEC_ID_MPEG2VIDEO, | 912 CODEC_ID_MPEG2VIDEO, |
| 885 mpegts_write_header, | 913 mpegts_write_header, |
| 886 mpegts_write_packet, | 914 mpegts_write_packet, |
| 887 mpegts_write_end, | 915 mpegts_write_end, |
| 888 }; | 916 }; |
| OLD | NEW |