| 
									
										
										
										
											2001-07-22 14:18:56 +00:00
										 |  |  | /*
 | 
					
						
							| 
									
										
										
										
											2002-10-15 10:22:23 +00:00
										 |  |  |  * MPEG1/2 mux/demux | 
					
						
							| 
									
										
										
										
											2002-05-25 22:34:32 +00:00
										 |  |  |  * Copyright (c) 2000, 2001, 2002 Fabrice Bellard. | 
					
						
							| 
									
										
										
										
											2001-07-22 14:18:56 +00:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2002-05-25 22:34:32 +00:00
										 |  |  |  * This library 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 of the License, or (at your option) any later version. | 
					
						
							| 
									
										
										
										
											2001-07-22 14:18:56 +00:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2002-05-25 22:34:32 +00:00
										 |  |  |  * This library is distributed in the hope that it will be useful, | 
					
						
							| 
									
										
										
										
											2001-07-22 14:18:56 +00:00
										 |  |  |  * but WITHOUT ANY WARRANTY; without even the implied warranty of | 
					
						
							| 
									
										
										
										
											2002-05-25 22:34:32 +00:00
										 |  |  |  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | 
					
						
							|  |  |  |  * Lesser General Public License for more details. | 
					
						
							| 
									
										
										
										
											2001-07-22 14:18:56 +00:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2002-05-25 22:34:32 +00:00
										 |  |  |  * You should have received a copy of the GNU Lesser General Public | 
					
						
							|  |  |  |  * License along with this library; if not, write to the Free Software | 
					
						
							|  |  |  |  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA | 
					
						
							| 
									
										
										
										
											2001-07-22 14:18:56 +00:00
										 |  |  |  */ | 
					
						
							|  |  |  | #include "avformat.h"
 | 
					
						
							| 
									
										
										
										
											2004-12-29 18:31:28 +00:00
										 |  |  | #include "bitstream.h"
 | 
					
						
							| 
									
										
										
										
											2001-07-22 14:18:56 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | #define MAX_PAYLOAD_SIZE 4096
 | 
					
						
							| 
									
										
										
										
											2003-11-10 18:47:52 +00:00
										 |  |  | //#define DEBUG_SEEK
 | 
					
						
							| 
									
										
										
										
											2001-07-22 14:18:56 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-01-13 22:02:49 +00:00
										 |  |  | #undef NDEBUG
 | 
					
						
							|  |  |  | #include <assert.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-10-03 02:42:01 +00:00
										 |  |  | typedef struct PacketDesc { | 
					
						
							|  |  |  |     int64_t pts; | 
					
						
							|  |  |  |     int64_t dts; | 
					
						
							|  |  |  |     int size; | 
					
						
							|  |  |  |     int unwritten_size; | 
					
						
							|  |  |  |     int flags; | 
					
						
							|  |  |  |     struct PacketDesc *next; | 
					
						
							|  |  |  | } PacketDesc; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-07-22 14:18:56 +00:00
										 |  |  | typedef struct { | 
					
						
							| 
									
										
										
										
											2004-10-03 02:42:01 +00:00
										 |  |  |     FifoBuffer fifo; | 
					
						
							| 
									
										
										
										
											2003-02-11 16:35:48 +00:00
										 |  |  |     uint8_t id; | 
					
						
							| 
									
										
										
										
											2001-07-22 14:18:56 +00:00
										 |  |  |     int max_buffer_size; /* in bytes */ | 
					
						
							| 
									
										
										
										
											2004-10-03 02:42:01 +00:00
										 |  |  |     int buffer_index; | 
					
						
							|  |  |  |     PacketDesc *predecode_packet; | 
					
						
							|  |  |  |     PacketDesc *premux_packet; | 
					
						
							|  |  |  |     PacketDesc **next_packet; | 
					
						
							| 
									
										
										
										
											2001-07-22 14:18:56 +00:00
										 |  |  |     int packet_number; | 
					
						
							| 
									
										
										
										
											2003-12-16 14:00:18 +00:00
										 |  |  |     uint8_t lpcm_header[3]; | 
					
						
							|  |  |  |     int lpcm_align; | 
					
						
							| 
									
										
										
										
											2004-11-21 03:37:33 +00:00
										 |  |  |     uint8_t *fifo_iframe_ptr; | 
					
						
							|  |  |  |     int align_iframe; | 
					
						
							| 
									
										
										
										
											2005-02-09 03:00:50 +00:00
										 |  |  |     int64_t vobu_start_pts; | 
					
						
							| 
									
										
										
										
											2001-07-22 14:18:56 +00:00
										 |  |  | } StreamInfo; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | typedef struct { | 
					
						
							|  |  |  |     int packet_size; /* required packet size */ | 
					
						
							|  |  |  |     int packet_number; | 
					
						
							|  |  |  |     int pack_header_freq;     /* frequency (in packets^-1) at which we send pack headers */ | 
					
						
							|  |  |  |     int system_header_freq; | 
					
						
							| 
									
										
										
										
											2003-12-16 11:25:30 +00:00
										 |  |  |     int system_header_size; | 
					
						
							| 
									
										
										
										
											2001-07-22 14:18:56 +00:00
										 |  |  |     int mux_rate; /* bitrate in units of 50 bytes/s */ | 
					
						
							|  |  |  |     /* stream info */ | 
					
						
							|  |  |  |     int audio_bound; | 
					
						
							|  |  |  |     int video_bound; | 
					
						
							| 
									
										
										
										
											2002-10-15 10:22:23 +00:00
										 |  |  |     int is_mpeg2; | 
					
						
							|  |  |  |     int is_vcd; | 
					
						
							| 
									
										
										
										
											2004-02-19 22:34:13 +00:00
										 |  |  |     int is_svcd; | 
					
						
							| 
									
										
										
										
											2004-10-03 18:21:45 +00:00
										 |  |  |     int is_dvd; | 
					
						
							| 
									
										
										
										
											2003-12-09 18:06:18 +00:00
										 |  |  |     int64_t last_scr; /* current system clock */ | 
					
						
							| 
									
										
										
										
											2004-02-19 22:34:13 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-10-01 20:05:04 +00:00
										 |  |  |     double vcd_padding_bitrate; //FIXME floats
 | 
					
						
							| 
									
										
										
										
											2004-02-19 22:34:13 +00:00
										 |  |  |     int64_t vcd_padding_bytes_written; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-07-22 14:18:56 +00:00
										 |  |  | } MpegMuxContext; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #define PACK_START_CODE             ((unsigned int)0x000001ba)
 | 
					
						
							|  |  |  | #define SYSTEM_HEADER_START_CODE    ((unsigned int)0x000001bb)
 | 
					
						
							| 
									
										
										
										
											2002-05-12 21:38:54 +00:00
										 |  |  | #define SEQUENCE_END_CODE           ((unsigned int)0x000001b7)
 | 
					
						
							| 
									
										
										
										
											2001-07-22 14:18:56 +00:00
										 |  |  | #define PACKET_START_CODE_MASK      ((unsigned int)0xffffff00)
 | 
					
						
							|  |  |  | #define PACKET_START_CODE_PREFIX    ((unsigned int)0x00000100)
 | 
					
						
							|  |  |  | #define ISO_11172_END_CODE          ((unsigned int)0x000001b9)
 | 
					
						
							|  |  |  |    | 
					
						
							|  |  |  | /* mpeg2 */ | 
					
						
							|  |  |  | #define PROGRAM_STREAM_MAP 0x1bc
 | 
					
						
							|  |  |  | #define PRIVATE_STREAM_1   0x1bd
 | 
					
						
							|  |  |  | #define PADDING_STREAM     0x1be
 | 
					
						
							|  |  |  | #define PRIVATE_STREAM_2   0x1bf
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #define AUDIO_ID 0xc0
 | 
					
						
							|  |  |  | #define VIDEO_ID 0xe0
 | 
					
						
							| 
									
										
										
										
											2003-12-16 14:00:18 +00:00
										 |  |  | #define AC3_ID   0x80
 | 
					
						
							| 
									
										
										
										
											2004-07-14 01:32:14 +00:00
										 |  |  | #define DTS_ID   0x8a
 | 
					
						
							| 
									
										
										
										
											2003-12-16 14:00:18 +00:00
										 |  |  | #define LPCM_ID  0xa0
 | 
					
						
							| 
									
										
										
										
											2001-07-22 14:18:56 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-01-17 22:02:07 +00:00
										 |  |  | static const int lpcm_freq_tab[4] = { 48000, 96000, 44100, 32000 }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-10-14 04:15:53 +00:00
										 |  |  | #ifdef CONFIG_ENCODERS
 | 
					
						
							| 
									
										
										
										
											2004-03-24 23:32:48 +00:00
										 |  |  | static AVOutputFormat mpeg1system_mux; | 
					
						
							|  |  |  | static AVOutputFormat mpeg1vcd_mux; | 
					
						
							|  |  |  | static AVOutputFormat mpeg2vob_mux; | 
					
						
							|  |  |  | static AVOutputFormat mpeg2svcd_mux; | 
					
						
							| 
									
										
										
										
											2004-10-03 18:21:45 +00:00
										 |  |  | static AVOutputFormat mpeg2dvd_mux; | 
					
						
							| 
									
										
										
										
											2002-10-15 10:22:23 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-07-22 14:18:56 +00:00
										 |  |  | static int put_pack_header(AVFormatContext *ctx,  | 
					
						
							| 
									
										
										
										
											2003-02-11 16:35:48 +00:00
										 |  |  |                            uint8_t *buf, int64_t timestamp) | 
					
						
							| 
									
										
										
										
											2001-07-22 14:18:56 +00:00
										 |  |  | { | 
					
						
							|  |  |  |     MpegMuxContext *s = ctx->priv_data; | 
					
						
							|  |  |  |     PutBitContext pb; | 
					
						
							|  |  |  |      | 
					
						
							| 
									
										
										
										
											2003-10-13 10:59:57 +00:00
										 |  |  |     init_put_bits(&pb, buf, 128); | 
					
						
							| 
									
										
										
										
											2001-07-22 14:18:56 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     put_bits(&pb, 32, PACK_START_CODE); | 
					
						
							| 
									
										
										
										
											2002-10-21 15:57:21 +00:00
										 |  |  |     if (s->is_mpeg2) { | 
					
						
							| 
									
										
										
										
											2003-07-15 22:15:37 +00:00
										 |  |  |         put_bits(&pb, 2, 0x1); | 
					
						
							| 
									
										
										
										
											2002-10-21 15:57:21 +00:00
										 |  |  |     } else { | 
					
						
							|  |  |  |         put_bits(&pb, 4, 0x2); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2003-02-11 16:35:48 +00:00
										 |  |  |     put_bits(&pb, 3, (uint32_t)((timestamp >> 30) & 0x07)); | 
					
						
							| 
									
										
										
										
											2001-07-22 14:18:56 +00:00
										 |  |  |     put_bits(&pb, 1, 1); | 
					
						
							| 
									
										
										
										
											2003-02-11 16:35:48 +00:00
										 |  |  |     put_bits(&pb, 15, (uint32_t)((timestamp >> 15) & 0x7fff)); | 
					
						
							| 
									
										
										
										
											2001-07-22 14:18:56 +00:00
										 |  |  |     put_bits(&pb, 1, 1); | 
					
						
							| 
									
										
										
										
											2003-02-11 16:35:48 +00:00
										 |  |  |     put_bits(&pb, 15, (uint32_t)((timestamp) & 0x7fff)); | 
					
						
							| 
									
										
										
										
											2001-07-22 14:18:56 +00:00
										 |  |  |     put_bits(&pb, 1, 1); | 
					
						
							| 
									
										
										
										
											2002-10-21 15:57:21 +00:00
										 |  |  |     if (s->is_mpeg2) { | 
					
						
							|  |  |  |         /* clock extension */ | 
					
						
							|  |  |  |         put_bits(&pb, 9, 0); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2001-07-22 14:18:56 +00:00
										 |  |  |     put_bits(&pb, 1, 1); | 
					
						
							|  |  |  |     put_bits(&pb, 22, s->mux_rate); | 
					
						
							|  |  |  |     put_bits(&pb, 1, 1); | 
					
						
							| 
									
										
										
										
											2002-10-21 15:57:21 +00:00
										 |  |  |     if (s->is_mpeg2) { | 
					
						
							| 
									
										
										
										
											2004-02-01 13:06:46 +00:00
										 |  |  |         put_bits(&pb, 1, 1); | 
					
						
							| 
									
										
										
										
											2002-10-21 15:57:21 +00:00
										 |  |  |         put_bits(&pb, 5, 0x1f); /* reserved */ | 
					
						
							|  |  |  |         put_bits(&pb, 3, 0); /* stuffing length */ | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2001-07-22 14:18:56 +00:00
										 |  |  |     flush_put_bits(&pb); | 
					
						
							| 
									
										
										
										
											2002-02-12 15:43:16 +00:00
										 |  |  |     return pbBufPtr(&pb) - pb.buf; | 
					
						
							| 
									
										
										
										
											2001-07-22 14:18:56 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-02-19 22:34:13 +00:00
										 |  |  | static int put_system_header(AVFormatContext *ctx, uint8_t *buf,int only_for_stream_id) | 
					
						
							| 
									
										
										
										
											2001-07-22 14:18:56 +00:00
										 |  |  | { | 
					
						
							|  |  |  |     MpegMuxContext *s = ctx->priv_data; | 
					
						
							| 
									
										
										
										
											2004-10-03 02:42:01 +00:00
										 |  |  |     int size, i, private_stream_coded, id; | 
					
						
							| 
									
										
										
										
											2001-07-22 14:18:56 +00:00
										 |  |  |     PutBitContext pb; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-10-13 10:59:57 +00:00
										 |  |  |     init_put_bits(&pb, buf, 128); | 
					
						
							| 
									
										
										
										
											2001-07-22 14:18:56 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     put_bits(&pb, 32, SYSTEM_HEADER_START_CODE); | 
					
						
							|  |  |  |     put_bits(&pb, 16, 0); | 
					
						
							|  |  |  |     put_bits(&pb, 1, 1); | 
					
						
							|  |  |  |      | 
					
						
							| 
									
										
										
										
											2004-10-03 02:42:01 +00:00
										 |  |  |     put_bits(&pb, 22, s->mux_rate); /* maximum bit rate of the multiplexed stream */ | 
					
						
							| 
									
										
										
										
											2001-07-22 14:18:56 +00:00
										 |  |  |     put_bits(&pb, 1, 1); /* marker */ | 
					
						
							| 
									
										
										
										
											2004-02-19 22:34:13 +00:00
										 |  |  |     if (s->is_vcd && only_for_stream_id==VIDEO_ID) { | 
					
						
							|  |  |  |         /* This header applies only to the video stream (see VCD standard p. IV-7)*/ | 
					
						
							|  |  |  |         put_bits(&pb, 6, 0); | 
					
						
							|  |  |  |     } else | 
					
						
							|  |  |  |         put_bits(&pb, 6, s->audio_bound); | 
					
						
							| 
									
										
										
										
											2001-07-22 14:18:56 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-04-26 22:16:06 +00:00
										 |  |  |     if (s->is_vcd) { | 
					
						
							|  |  |  |         /* see VCD standard, p. IV-7*/ | 
					
						
							|  |  |  |         put_bits(&pb, 1, 0);  | 
					
						
							|  |  |  |         put_bits(&pb, 1, 1); | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |         put_bits(&pb, 1, 0); /* variable bitrate*/ | 
					
						
							|  |  |  |         put_bits(&pb, 1, 0); /* non constrainted bit stream */ | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2001-07-22 14:18:56 +00:00
										 |  |  |      | 
					
						
							| 
									
										
										
										
											2004-11-21 03:37:33 +00:00
										 |  |  |     if (s->is_vcd || s->is_dvd) { | 
					
						
							| 
									
										
										
										
											2004-02-19 22:34:13 +00:00
										 |  |  |         /* see VCD standard p IV-7 */ | 
					
						
							|  |  |  |         put_bits(&pb, 1, 1); /* audio locked */ | 
					
						
							|  |  |  |         put_bits(&pb, 1, 1); /* video locked */ | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |         put_bits(&pb, 1, 0); /* audio locked */ | 
					
						
							|  |  |  |         put_bits(&pb, 1, 0); /* video locked */ | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-07-22 14:18:56 +00:00
										 |  |  |     put_bits(&pb, 1, 1); /* marker */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-02-19 22:34:13 +00:00
										 |  |  |     if (s->is_vcd && only_for_stream_id==AUDIO_ID) { | 
					
						
							|  |  |  |         /* This header applies only to the audio stream (see VCD standard p. IV-7)*/ | 
					
						
							|  |  |  |         put_bits(&pb, 5, 0); | 
					
						
							|  |  |  |     } else | 
					
						
							|  |  |  |         put_bits(&pb, 5, s->video_bound); | 
					
						
							| 
									
										
										
										
											2001-07-22 14:18:56 +00:00
										 |  |  |      | 
					
						
							| 
									
										
										
										
											2004-11-21 03:37:33 +00:00
										 |  |  |     if (s->is_dvd) { | 
					
						
							|  |  |  |         put_bits(&pb, 1, 0);    /* packet_rate_restriction_flag */ | 
					
						
							|  |  |  |         put_bits(&pb, 7, 0x7f); /* reserved byte */ | 
					
						
							|  |  |  |     } else | 
					
						
							|  |  |  |         put_bits(&pb, 8, 0xff); /* reserved byte */ | 
					
						
							|  |  |  |      | 
					
						
							|  |  |  |     /* DVD-Video Stream_bound entries
 | 
					
						
							|  |  |  |     id (0xB9) video, maximum P-STD for stream 0xE0. (P-STD_buffer_bound_scale = 1)  | 
					
						
							|  |  |  |     id (0xB8) audio, maximum P-STD for any MPEG audio (0xC0 to 0xC7) streams. If there are none set to 4096 (32x128). (P-STD_buffer_bound_scale = 0)  | 
					
						
							|  |  |  |     id (0xBD) private stream 1 (audio other than MPEG and subpictures). (P-STD_buffer_bound_scale = 1)  | 
					
						
							|  |  |  |     id (0xBF) private stream 2, NAV packs, set to 2x1024. */ | 
					
						
							|  |  |  |     if (s->is_dvd) { | 
					
						
							|  |  |  |          | 
					
						
							|  |  |  |         int P_STD_max_video = 0; | 
					
						
							|  |  |  |         int P_STD_max_mpeg_audio = 0; | 
					
						
							|  |  |  |         int P_STD_max_mpeg_PS1 = 0; | 
					
						
							| 
									
										
										
										
											2004-02-19 22:34:13 +00:00
										 |  |  |          | 
					
						
							| 
									
										
										
										
											2004-11-21 03:37:33 +00:00
										 |  |  |         for(i=0;i<ctx->nb_streams;i++) { | 
					
						
							|  |  |  |             StreamInfo *stream = ctx->streams[i]->priv_data; | 
					
						
							| 
									
										
										
										
											2004-02-19 22:34:13 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |             id = stream->id; | 
					
						
							| 
									
										
										
										
											2004-11-21 03:37:33 +00:00
										 |  |  |             if (id == 0xbd && stream->max_buffer_size > P_STD_max_mpeg_PS1) { | 
					
						
							|  |  |  |                 P_STD_max_mpeg_PS1 = stream->max_buffer_size; | 
					
						
							|  |  |  |             } else if (id >= 0xc0 && id <= 0xc7 && stream->max_buffer_size > P_STD_max_mpeg_audio) { | 
					
						
							|  |  |  |                 P_STD_max_mpeg_audio = stream->max_buffer_size; | 
					
						
							|  |  |  |             } else if (id == 0xe0 && stream->max_buffer_size > P_STD_max_video) { | 
					
						
							|  |  |  |                 P_STD_max_video = stream->max_buffer_size; | 
					
						
							| 
									
										
										
										
											2004-02-19 22:34:13 +00:00
										 |  |  |             } | 
					
						
							| 
									
										
										
										
											2004-11-21 03:37:33 +00:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         /* video */ | 
					
						
							|  |  |  |         put_bits(&pb, 8, 0xb9); /* stream ID */ | 
					
						
							|  |  |  |         put_bits(&pb, 2, 3); | 
					
						
							|  |  |  |         put_bits(&pb, 1, 1); | 
					
						
							|  |  |  |         put_bits(&pb, 13, P_STD_max_video / 1024); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         /* audio */ | 
					
						
							|  |  |  |         if (P_STD_max_mpeg_audio == 0) | 
					
						
							|  |  |  |             P_STD_max_mpeg_audio = 4096; | 
					
						
							|  |  |  |         put_bits(&pb, 8, 0xb8); /* stream ID */ | 
					
						
							|  |  |  |         put_bits(&pb, 2, 3); | 
					
						
							|  |  |  |         put_bits(&pb, 1, 0); | 
					
						
							|  |  |  |         put_bits(&pb, 13, P_STD_max_mpeg_audio / 128); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         /* private stream 1 */ | 
					
						
							|  |  |  |         put_bits(&pb, 8, 0xbd); /* stream ID */ | 
					
						
							|  |  |  |         put_bits(&pb, 2, 3); | 
					
						
							|  |  |  |         put_bits(&pb, 1, 0); | 
					
						
							|  |  |  |         put_bits(&pb, 13, P_STD_max_mpeg_PS1 / 128); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         /* private stream 2 */ | 
					
						
							|  |  |  |         put_bits(&pb, 8, 0xbf); /* stream ID */ | 
					
						
							|  |  |  |         put_bits(&pb, 2, 3); | 
					
						
							|  |  |  |         put_bits(&pb, 1, 1); | 
					
						
							|  |  |  |         put_bits(&pb, 13, 2); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else { | 
					
						
							|  |  |  |         /* audio stream info */ | 
					
						
							|  |  |  |         private_stream_coded = 0; | 
					
						
							|  |  |  |         for(i=0;i<ctx->nb_streams;i++) { | 
					
						
							|  |  |  |             StreamInfo *stream = ctx->streams[i]->priv_data; | 
					
						
							|  |  |  |              | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             /* For VCDs, only include the stream info for the stream
 | 
					
						
							|  |  |  |             that the pack which contains this system belongs to. | 
					
						
							|  |  |  |             (see VCD standard p. IV-7) */ | 
					
						
							|  |  |  |             if ( !s->is_vcd || stream->id==only_for_stream_id | 
					
						
							|  |  |  |                 || only_for_stream_id==0) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 id = stream->id; | 
					
						
							|  |  |  |                 if (id < 0xc0) { | 
					
						
							|  |  |  |                     /* special case for private streams (AC3 use that) */ | 
					
						
							|  |  |  |                     if (private_stream_coded) | 
					
						
							|  |  |  |                         continue; | 
					
						
							|  |  |  |                     private_stream_coded = 1; | 
					
						
							|  |  |  |                     id = 0xbd; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |                 put_bits(&pb, 8, id); /* stream ID */ | 
					
						
							|  |  |  |                 put_bits(&pb, 2, 3); | 
					
						
							|  |  |  |                 if (id < 0xe0) { | 
					
						
							|  |  |  |                     /* audio */ | 
					
						
							|  |  |  |                     put_bits(&pb, 1, 0); | 
					
						
							|  |  |  |                     put_bits(&pb, 13, stream->max_buffer_size / 128); | 
					
						
							|  |  |  |                 } else { | 
					
						
							|  |  |  |                     /* video */ | 
					
						
							|  |  |  |                     put_bits(&pb, 1, 1); | 
					
						
							|  |  |  |                     put_bits(&pb, 13, stream->max_buffer_size / 1024); | 
					
						
							|  |  |  |                 } | 
					
						
							| 
									
										
										
										
											2004-02-19 22:34:13 +00:00
										 |  |  |             } | 
					
						
							| 
									
										
										
										
											2001-07-22 14:18:56 +00:00
										 |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2004-11-21 03:37:33 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-07-22 14:18:56 +00:00
										 |  |  |     flush_put_bits(&pb); | 
					
						
							| 
									
										
										
										
											2002-02-12 15:43:16 +00:00
										 |  |  |     size = pbBufPtr(&pb) - pb.buf; | 
					
						
							| 
									
										
										
										
											2001-07-22 14:18:56 +00:00
										 |  |  |     /* patch packet size */ | 
					
						
							|  |  |  |     buf[4] = (size - 6) >> 8; | 
					
						
							|  |  |  |     buf[5] = (size - 6) & 0xff; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return size; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-12-16 11:25:30 +00:00
										 |  |  | static int get_system_header_size(AVFormatContext *ctx) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     int buf_index, i, private_stream_coded; | 
					
						
							|  |  |  |     StreamInfo *stream; | 
					
						
							| 
									
										
										
										
											2004-11-21 03:37:33 +00:00
										 |  |  |     MpegMuxContext *s = ctx->priv_data; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (s->is_dvd) | 
					
						
							|  |  |  |        return 18; // DVD-Video system headers are 18 bytes fixed length.
 | 
					
						
							| 
									
										
										
										
											2003-12-16 11:25:30 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     buf_index = 12; | 
					
						
							|  |  |  |     private_stream_coded = 0; | 
					
						
							|  |  |  |     for(i=0;i<ctx->nb_streams;i++) { | 
					
						
							|  |  |  |         stream = ctx->streams[i]->priv_data; | 
					
						
							|  |  |  |         if (stream->id < 0xc0) { | 
					
						
							|  |  |  |             if (private_stream_coded) | 
					
						
							|  |  |  |                 continue; | 
					
						
							|  |  |  |             private_stream_coded = 1; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         buf_index += 3; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return buf_index; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-07-22 14:18:56 +00:00
										 |  |  | static int mpeg_mux_init(AVFormatContext *ctx) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2002-05-20 16:29:40 +00:00
										 |  |  |     MpegMuxContext *s = ctx->priv_data; | 
					
						
							| 
									
										
										
										
											2004-07-14 01:32:14 +00:00
										 |  |  |     int bitrate, i, mpa_id, mpv_id, ac3_id, dts_id, lpcm_id, j; | 
					
						
							| 
									
										
										
										
											2001-07-22 14:18:56 +00:00
										 |  |  |     AVStream *st; | 
					
						
							|  |  |  |     StreamInfo *stream; | 
					
						
							| 
									
										
										
										
											2004-02-19 22:34:13 +00:00
										 |  |  |     int audio_bitrate; | 
					
						
							|  |  |  |     int video_bitrate; | 
					
						
							| 
									
										
										
										
											2001-07-22 14:18:56 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     s->packet_number = 0; | 
					
						
							| 
									
										
										
										
											2002-10-15 10:22:23 +00:00
										 |  |  |     s->is_vcd = (ctx->oformat == &mpeg1vcd_mux); | 
					
						
							| 
									
										
										
										
											2004-02-19 22:34:13 +00:00
										 |  |  |     s->is_svcd = (ctx->oformat == &mpeg2svcd_mux); | 
					
						
							| 
									
										
										
										
											2004-10-03 18:21:45 +00:00
										 |  |  |     s->is_mpeg2 = (ctx->oformat == &mpeg2vob_mux || ctx->oformat == &mpeg2svcd_mux || ctx->oformat == &mpeg2dvd_mux); | 
					
						
							|  |  |  |     s->is_dvd = (ctx->oformat == &mpeg2dvd_mux); | 
					
						
							| 
									
										
										
										
											2002-10-15 10:22:23 +00:00
										 |  |  |      | 
					
						
							| 
									
										
										
										
											2004-10-06 22:29:30 +00:00
										 |  |  |     if(ctx->packet_size) | 
					
						
							|  |  |  |         s->packet_size = ctx->packet_size; | 
					
						
							| 
									
										
										
										
											2002-05-12 21:38:54 +00:00
										 |  |  |     else | 
					
						
							|  |  |  |         s->packet_size = 2048; | 
					
						
							| 
									
										
										
										
											2004-10-06 22:29:30 +00:00
										 |  |  |         | 
					
						
							| 
									
										
										
										
											2004-02-19 22:34:13 +00:00
										 |  |  |     s->vcd_padding_bytes_written = 0; | 
					
						
							|  |  |  |     s->vcd_padding_bitrate=0; | 
					
						
							| 
									
										
										
										
											2002-05-12 21:38:54 +00:00
										 |  |  |          | 
					
						
							| 
									
										
										
										
											2001-07-22 14:18:56 +00:00
										 |  |  |     s->audio_bound = 0; | 
					
						
							|  |  |  |     s->video_bound = 0; | 
					
						
							|  |  |  |     mpa_id = AUDIO_ID; | 
					
						
							| 
									
										
										
										
											2003-12-16 14:00:18 +00:00
										 |  |  |     ac3_id = AC3_ID; | 
					
						
							| 
									
										
										
										
											2004-07-14 01:32:14 +00:00
										 |  |  |     dts_id = DTS_ID; | 
					
						
							| 
									
										
										
										
											2001-07-22 14:18:56 +00:00
										 |  |  |     mpv_id = VIDEO_ID; | 
					
						
							| 
									
										
										
										
											2003-12-16 14:00:18 +00:00
										 |  |  |     lpcm_id = LPCM_ID; | 
					
						
							| 
									
										
										
										
											2001-07-22 14:18:56 +00:00
										 |  |  |     for(i=0;i<ctx->nb_streams;i++) { | 
					
						
							|  |  |  |         st = ctx->streams[i]; | 
					
						
							|  |  |  |         stream = av_mallocz(sizeof(StreamInfo)); | 
					
						
							|  |  |  |         if (!stream) | 
					
						
							|  |  |  |             goto fail; | 
					
						
							|  |  |  |         st->priv_data = stream; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-10-03 12:17:46 +00:00
										 |  |  |         av_set_pts_info(st, 64, 1, 90000); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-07-22 14:18:56 +00:00
										 |  |  |         switch(st->codec.codec_type) { | 
					
						
							|  |  |  |         case CODEC_TYPE_AUDIO: | 
					
						
							| 
									
										
										
										
											2003-12-16 14:00:18 +00:00
										 |  |  |             if (st->codec.codec_id == CODEC_ID_AC3) { | 
					
						
							| 
									
										
										
										
											2001-07-22 14:18:56 +00:00
										 |  |  |                 stream->id = ac3_id++; | 
					
						
							| 
									
										
										
										
											2004-07-14 01:32:14 +00:00
										 |  |  |             } else if (st->codec.codec_id == CODEC_ID_DTS) { | 
					
						
							|  |  |  |                 stream->id = dts_id++; | 
					
						
							| 
									
										
										
										
											2003-12-16 14:00:18 +00:00
										 |  |  |             } else if (st->codec.codec_id == CODEC_ID_PCM_S16BE) { | 
					
						
							|  |  |  |                 stream->id = lpcm_id++; | 
					
						
							|  |  |  |                 for(j = 0; j < 4; j++) { | 
					
						
							|  |  |  |                     if (lpcm_freq_tab[j] == st->codec.sample_rate) | 
					
						
							|  |  |  |                         break; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |                 if (j == 4) | 
					
						
							|  |  |  |                     goto fail; | 
					
						
							|  |  |  |                 if (st->codec.channels > 8) | 
					
						
							|  |  |  |                     return -1; | 
					
						
							|  |  |  |                 stream->lpcm_header[0] = 0x0c; | 
					
						
							|  |  |  |                 stream->lpcm_header[1] = (st->codec.channels - 1) | (j << 4); | 
					
						
							|  |  |  |                 stream->lpcm_header[2] = 0x80; | 
					
						
							|  |  |  |                 stream->lpcm_align = st->codec.channels * 2; | 
					
						
							|  |  |  |             } else { | 
					
						
							| 
									
										
										
										
											2001-07-22 14:18:56 +00:00
										 |  |  |                 stream->id = mpa_id++; | 
					
						
							| 
									
										
										
										
											2003-12-16 14:00:18 +00:00
										 |  |  |             } | 
					
						
							| 
									
										
										
										
											2004-04-26 22:16:06 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |             /* This value HAS to be used for VCD (see VCD standard, p. IV-7).
 | 
					
						
							|  |  |  |                Right now it is also used for everything else.*/ | 
					
						
							| 
									
										
										
										
											2001-07-22 14:18:56 +00:00
										 |  |  |             stream->max_buffer_size = 4 * 1024;  | 
					
						
							|  |  |  |             s->audio_bound++; | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |         case CODEC_TYPE_VIDEO: | 
					
						
							|  |  |  |             stream->id = mpv_id++; | 
					
						
							| 
									
										
										
										
											2004-10-03 03:14:09 +00:00
										 |  |  |             if (st->codec.rc_buffer_size) | 
					
						
							|  |  |  |                 stream->max_buffer_size = 6*1024 + st->codec.rc_buffer_size/8; | 
					
						
							|  |  |  |             else | 
					
						
							|  |  |  |                 stream->max_buffer_size = 230*1024; //FIXME this is probably too small as default
 | 
					
						
							|  |  |  | #if 0
 | 
					
						
							| 
									
										
										
										
											2004-04-26 22:16:06 +00:00
										 |  |  |                 /* see VCD standard, p. IV-7*/ | 
					
						
							|  |  |  |                 stream->max_buffer_size = 46 * 1024;  | 
					
						
							|  |  |  |             else | 
					
						
							|  |  |  |                 /* This value HAS to be used for SVCD (see SVCD standard, p. 26 V.2.3.2).
 | 
					
						
							|  |  |  |                    Right now it is also used for everything else.*/ | 
					
						
							|  |  |  |                 stream->max_buffer_size = 230 * 1024;  | 
					
						
							| 
									
										
										
										
											2004-10-03 03:14:09 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2001-07-22 14:18:56 +00:00
										 |  |  |             s->video_bound++; | 
					
						
							|  |  |  |             break; | 
					
						
							| 
									
										
										
										
											2002-05-09 01:19:33 +00:00
										 |  |  |         default: | 
					
						
							| 
									
										
										
										
											2004-10-01 13:16:16 +00:00
										 |  |  |             return -1; | 
					
						
							| 
									
										
										
										
											2001-07-22 14:18:56 +00:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2004-12-01 02:28:28 +00:00
										 |  |  |         fifo_init(&stream->fifo, 16); | 
					
						
							| 
									
										
										
										
											2004-10-03 02:42:01 +00:00
										 |  |  |         stream->next_packet= &stream->premux_packet; | 
					
						
							| 
									
										
										
										
											2001-07-22 14:18:56 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2004-02-19 22:34:13 +00:00
										 |  |  |     bitrate = 0; | 
					
						
							|  |  |  |     audio_bitrate = 0; | 
					
						
							|  |  |  |     video_bitrate = 0; | 
					
						
							| 
									
										
										
										
											2001-07-22 14:18:56 +00:00
										 |  |  |     for(i=0;i<ctx->nb_streams;i++) { | 
					
						
							| 
									
										
										
										
											2004-10-03 02:42:01 +00:00
										 |  |  |         int codec_rate; | 
					
						
							| 
									
										
										
										
											2001-07-22 14:18:56 +00:00
										 |  |  |         st = ctx->streams[i]; | 
					
						
							| 
									
										
										
										
											2004-02-19 22:34:13 +00:00
										 |  |  |         stream = (StreamInfo*) st->priv_data; | 
					
						
							| 
									
										
										
										
											2004-10-03 02:42:01 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         if(st->codec.rc_max_rate || stream->id==VIDEO_ID) | 
					
						
							|  |  |  |             codec_rate= st->codec.rc_max_rate; | 
					
						
							|  |  |  |         else | 
					
						
							|  |  |  |             codec_rate= st->codec.bit_rate; | 
					
						
							|  |  |  |                  | 
					
						
							|  |  |  |         if(!codec_rate) | 
					
						
							|  |  |  |             codec_rate= (1<<21)*8*50/ctx->nb_streams; | 
					
						
							|  |  |  |              | 
					
						
							|  |  |  |         bitrate += codec_rate; | 
					
						
							| 
									
										
										
										
											2004-02-19 22:34:13 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         if (stream->id==AUDIO_ID) | 
					
						
							| 
									
										
										
										
											2004-10-03 02:42:01 +00:00
										 |  |  |             audio_bitrate += codec_rate; | 
					
						
							| 
									
										
										
										
											2004-02-19 22:34:13 +00:00
										 |  |  |         else if (stream->id==VIDEO_ID) | 
					
						
							| 
									
										
										
										
											2004-10-03 02:42:01 +00:00
										 |  |  |             video_bitrate += codec_rate; | 
					
						
							| 
									
										
										
										
											2004-02-19 22:34:13 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2004-10-06 22:29:30 +00:00
										 |  |  |      | 
					
						
							|  |  |  |     if(ctx->mux_rate){ | 
					
						
							|  |  |  |         s->mux_rate= (ctx->mux_rate + (8 * 50) - 1) / (8 * 50); | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |         /* we increase slightly the bitrate to take into account the
 | 
					
						
							|  |  |  |            headers. XXX: compute it exactly */ | 
					
						
							|  |  |  |         bitrate += bitrate*5/100; | 
					
						
							|  |  |  |         bitrate += 10000; | 
					
						
							|  |  |  |         s->mux_rate = (bitrate + (8 * 50) - 1) / (8 * 50); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2004-02-19 22:34:13 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if (s->is_vcd) { | 
					
						
							|  |  |  |         double overhead_rate; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         /* The VCD standard mandates that the mux_rate field is 3528
 | 
					
						
							|  |  |  |            (see standard p. IV-6). | 
					
						
							|  |  |  |            The value is actually "wrong", i.e. if you calculate | 
					
						
							|  |  |  |            it using the normal formula and the 75 sectors per second transfer | 
					
						
							|  |  |  |            rate you get a different value because the real pack size is 2324, | 
					
						
							|  |  |  |            not 2352. But the standard explicitly specifies that the mux_rate | 
					
						
							|  |  |  |            field in the header must have this value.*/ | 
					
						
							| 
									
										
										
										
											2004-10-06 22:29:30 +00:00
										 |  |  | //        s->mux_rate=2352 * 75 / 50;    /* = 3528*/
 | 
					
						
							| 
									
										
										
										
											2004-02-19 22:34:13 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         /* The VCD standard states that the muxed stream must be
 | 
					
						
							|  |  |  |            exactly 75 packs / second (the data rate of a single speed cdrom). | 
					
						
							|  |  |  |            Since the video bitrate (probably 1150000 bits/sec) will be below | 
					
						
							|  |  |  |            the theoretical maximum we have to add some padding packets | 
					
						
							|  |  |  |            to make up for the lower data rate. | 
					
						
							|  |  |  |            (cf. VCD standard p. IV-6 )*/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         /* Add the header overhead to the data rate.
 | 
					
						
							|  |  |  |            2279 data bytes per audio pack, 2294 data bytes per video pack*/ | 
					
						
							|  |  |  |         overhead_rate = ((audio_bitrate / 8.0) / 2279) * (2324 - 2279); | 
					
						
							|  |  |  |         overhead_rate += ((video_bitrate / 8.0) / 2294) * (2324 - 2294); | 
					
						
							|  |  |  |         overhead_rate *= 8; | 
					
						
							|  |  |  |          | 
					
						
							|  |  |  |         /* Add padding so that the full bitrate is 2324*75 bytes/sec */ | 
					
						
							|  |  |  |         s->vcd_padding_bitrate = 2324 * 75 * 8 - (bitrate + overhead_rate); | 
					
						
							| 
									
										
										
										
											2001-07-22 14:18:56 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2002-05-12 21:38:54 +00:00
										 |  |  |      | 
					
						
							| 
									
										
										
										
											2002-10-15 10:22:23 +00:00
										 |  |  |     if (s->is_vcd || s->is_mpeg2) | 
					
						
							| 
									
										
										
										
											2002-05-12 21:38:54 +00:00
										 |  |  |         /* every packet */ | 
					
						
							|  |  |  |         s->pack_header_freq = 1; | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |         /* every 2 seconds */ | 
					
						
							|  |  |  |         s->pack_header_freq = 2 * bitrate / s->packet_size / 8; | 
					
						
							| 
									
										
										
										
											2003-10-28 10:55:15 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     /* the above seems to make pack_header_freq zero sometimes */ | 
					
						
							|  |  |  |     if (s->pack_header_freq == 0) | 
					
						
							|  |  |  |        s->pack_header_freq = 1; | 
					
						
							| 
									
										
										
										
											2002-05-12 21:38:54 +00:00
										 |  |  |      | 
					
						
							| 
									
										
										
										
											2002-10-21 15:57:21 +00:00
										 |  |  |     if (s->is_mpeg2) | 
					
						
							|  |  |  |         /* every 200 packets. Need to look at the spec.  */ | 
					
						
							|  |  |  |         s->system_header_freq = s->pack_header_freq * 40; | 
					
						
							|  |  |  |     else if (s->is_vcd) | 
					
						
							| 
									
										
										
										
											2004-02-19 22:34:13 +00:00
										 |  |  |         /* the standard mandates that there are only two system headers
 | 
					
						
							|  |  |  |            in the whole file: one in the first packet of each stream. | 
					
						
							|  |  |  |            (see standard p. IV-7 and IV-8) */ | 
					
						
							|  |  |  |         s->system_header_freq = 0x7fffffff; | 
					
						
							| 
									
										
										
										
											2002-05-12 21:38:54 +00:00
										 |  |  |     else | 
					
						
							|  |  |  |         s->system_header_freq = s->pack_header_freq * 5; | 
					
						
							|  |  |  |      | 
					
						
							| 
									
										
										
										
											2001-07-22 14:18:56 +00:00
										 |  |  |     for(i=0;i<ctx->nb_streams;i++) { | 
					
						
							|  |  |  |         stream = ctx->streams[i]->priv_data; | 
					
						
							|  |  |  |         stream->packet_number = 0; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2003-12-16 11:25:30 +00:00
										 |  |  |     s->system_header_size = get_system_header_size(ctx); | 
					
						
							| 
									
										
										
										
											2003-12-09 18:06:18 +00:00
										 |  |  |     s->last_scr = 0; | 
					
						
							| 
									
										
										
										
											2001-07-22 14:18:56 +00:00
										 |  |  |     return 0; | 
					
						
							|  |  |  |  fail: | 
					
						
							|  |  |  |     for(i=0;i<ctx->nb_streams;i++) { | 
					
						
							| 
									
										
										
										
											2002-05-18 23:11:09 +00:00
										 |  |  |         av_free(ctx->streams[i]->priv_data); | 
					
						
							| 
									
										
										
										
											2001-07-22 14:18:56 +00:00
										 |  |  |     } | 
					
						
							|  |  |  |     return -ENOMEM; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-12-09 18:06:18 +00:00
										 |  |  | static inline void put_timestamp(ByteIOContext *pb, int id, int64_t timestamp) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     put_byte(pb,  | 
					
						
							|  |  |  |              (id << 4) |  | 
					
						
							|  |  |  |              (((timestamp >> 30) & 0x07) << 1) |  | 
					
						
							|  |  |  |              1); | 
					
						
							|  |  |  |     put_be16(pb, (uint16_t)((((timestamp >> 15) & 0x7fff) << 1) | 1)); | 
					
						
							|  |  |  |     put_be16(pb, (uint16_t)((((timestamp) & 0x7fff) << 1) | 1)); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-12-16 11:25:30 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-02-19 22:34:13 +00:00
										 |  |  | /* return the number of padding bytes that should be inserted into
 | 
					
						
							|  |  |  |    the multiplexed stream.*/ | 
					
						
							|  |  |  | static int get_vcd_padding_size(AVFormatContext *ctx, int64_t pts) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     MpegMuxContext *s = ctx->priv_data; | 
					
						
							|  |  |  |     int pad_bytes = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (s->vcd_padding_bitrate > 0 && pts!=AV_NOPTS_VALUE) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         int64_t full_pad_bytes; | 
					
						
							|  |  |  |          | 
					
						
							| 
									
										
										
										
											2004-10-03 02:42:01 +00:00
										 |  |  |         full_pad_bytes = (int64_t)((s->vcd_padding_bitrate * (pts / 90000.0)) / 8.0); //FIXME this is wrong
 | 
					
						
							| 
									
										
										
										
											2004-02-19 22:34:13 +00:00
										 |  |  |         pad_bytes = (int) (full_pad_bytes - s->vcd_padding_bytes_written); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (pad_bytes<0) | 
					
						
							|  |  |  |             /* might happen if we have already padded to a later timestamp. This
 | 
					
						
							|  |  |  |                can occur if another stream has already advanced further.*/ | 
					
						
							|  |  |  |             pad_bytes=0; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return pad_bytes; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-02-24 19:08:50 +00:00
										 |  |  | #if 0 /* unused, remove? */
 | 
					
						
							| 
									
										
										
										
											2003-12-16 11:25:30 +00:00
										 |  |  | /* return the exact available payload size for the next packet for
 | 
					
						
							|  |  |  |    stream 'stream_index'. 'pts' and 'dts' are only used to know if | 
					
						
							|  |  |  |    timestamps are needed in the packet header. */ | 
					
						
							|  |  |  | static int get_packet_payload_size(AVFormatContext *ctx, int stream_index, | 
					
						
							|  |  |  |                                    int64_t pts, int64_t dts) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     MpegMuxContext *s = ctx->priv_data; | 
					
						
							|  |  |  |     int buf_index; | 
					
						
							|  |  |  |     StreamInfo *stream; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-02-19 22:34:13 +00:00
										 |  |  |     stream = ctx->streams[stream_index]->priv_data; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-12-16 11:25:30 +00:00
										 |  |  |     buf_index = 0; | 
					
						
							|  |  |  |     if (((s->packet_number % s->pack_header_freq) == 0)) { | 
					
						
							|  |  |  |         /* pack header size */ | 
					
						
							|  |  |  |         if (s->is_mpeg2)  | 
					
						
							|  |  |  |             buf_index += 14; | 
					
						
							|  |  |  |         else | 
					
						
							|  |  |  |             buf_index += 12; | 
					
						
							| 
									
										
										
										
											2004-02-19 22:34:13 +00:00
										 |  |  |          | 
					
						
							|  |  |  |         if (s->is_vcd) { | 
					
						
							|  |  |  |             /* there is exactly one system header for each stream in a VCD MPEG,
 | 
					
						
							|  |  |  |                One in the very first video packet and one in the very first | 
					
						
							|  |  |  |                audio packet (see VCD standard p. IV-7 and IV-8).*/ | 
					
						
							|  |  |  |              | 
					
						
							|  |  |  |             if (stream->packet_number==0) | 
					
						
							|  |  |  |                 /* The system headers refer only to the stream they occur in,
 | 
					
						
							|  |  |  |                    so they have a constant size.*/ | 
					
						
							|  |  |  |                 buf_index += 15; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         } else {             | 
					
						
							|  |  |  |             if ((s->packet_number % s->system_header_freq) == 0) | 
					
						
							|  |  |  |                 buf_index += s->system_header_size; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2003-12-16 11:25:30 +00:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-04-26 22:16:06 +00:00
										 |  |  |     if ((s->is_vcd && stream->packet_number==0) | 
					
						
							|  |  |  |         || (s->is_svcd && s->packet_number==0)) | 
					
						
							| 
									
										
										
										
											2004-02-19 22:34:13 +00:00
										 |  |  |         /* the first pack of each stream contains only the pack header,
 | 
					
						
							|  |  |  |            the system header and some padding (see VCD standard p. IV-6)  | 
					
						
							|  |  |  |            Add the padding size, so that the actual payload becomes 0.*/ | 
					
						
							|  |  |  |         buf_index += s->packet_size - buf_index; | 
					
						
							|  |  |  |     else { | 
					
						
							|  |  |  |         /* packet header size */ | 
					
						
							|  |  |  |         buf_index += 6; | 
					
						
							| 
									
										
										
										
											2004-04-26 22:16:06 +00:00
										 |  |  |         if (s->is_mpeg2) { | 
					
						
							| 
									
										
										
										
											2003-12-16 14:00:18 +00:00
										 |  |  |             buf_index += 3; | 
					
						
							| 
									
										
										
										
											2004-04-26 22:16:06 +00:00
										 |  |  |             if (stream->packet_number==0) | 
					
						
							|  |  |  |                 buf_index += 3; /* PES extension */ | 
					
						
							|  |  |  |             buf_index += 1;    /* obligatory stuffing byte */ | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2004-02-19 22:34:13 +00:00
										 |  |  |         if (pts != AV_NOPTS_VALUE) { | 
					
						
							|  |  |  |             if (dts != pts) | 
					
						
							|  |  |  |                 buf_index += 5 + 5; | 
					
						
							|  |  |  |             else | 
					
						
							|  |  |  |                 buf_index += 5; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         } else { | 
					
						
							|  |  |  |             if (!s->is_mpeg2) | 
					
						
							|  |  |  |                 buf_index++; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |      | 
					
						
							|  |  |  |         if (stream->id < 0xc0) { | 
					
						
							|  |  |  |             /* AC3/LPCM private data header */ | 
					
						
							|  |  |  |             buf_index += 4; | 
					
						
							|  |  |  |             if (stream->id >= 0xa0) { | 
					
						
							|  |  |  |                 int n; | 
					
						
							|  |  |  |                 buf_index += 3; | 
					
						
							|  |  |  |                 /* NOTE: we round the payload size to an integer number of
 | 
					
						
							|  |  |  |                    LPCM samples */ | 
					
						
							|  |  |  |                 n = (s->packet_size - buf_index) % stream->lpcm_align; | 
					
						
							|  |  |  |                 if (n) | 
					
						
							|  |  |  |                     buf_index += (stream->lpcm_align - n); | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2003-12-16 14:00:18 +00:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2004-02-19 22:34:13 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         if (s->is_vcd && stream->id == AUDIO_ID) | 
					
						
							|  |  |  |             /* The VCD standard demands that 20 zero bytes follow
 | 
					
						
							|  |  |  |                each audio packet (see standard p. IV-8).*/ | 
					
						
							|  |  |  |             buf_index+=20; | 
					
						
							| 
									
										
										
										
											2003-12-16 11:25:30 +00:00
										 |  |  |     } | 
					
						
							|  |  |  |     return s->packet_size - buf_index;  | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2005-02-24 19:08:50 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2003-12-16 11:25:30 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-02-19 22:34:13 +00:00
										 |  |  | /* Write an MPEG padding packet header. */ | 
					
						
							| 
									
										
										
										
											2004-10-01 20:05:04 +00:00
										 |  |  | static void put_padding_packet(AVFormatContext *ctx, ByteIOContext *pb,int packet_bytes) | 
					
						
							| 
									
										
										
										
											2004-02-19 22:34:13 +00:00
										 |  |  | { | 
					
						
							|  |  |  |     MpegMuxContext *s = ctx->priv_data; | 
					
						
							| 
									
										
										
										
											2004-10-01 20:05:04 +00:00
										 |  |  |     int i; | 
					
						
							|  |  |  |      | 
					
						
							|  |  |  |     put_be32(pb, PADDING_STREAM); | 
					
						
							|  |  |  |     put_be16(pb, packet_bytes - 6); | 
					
						
							| 
									
										
										
										
											2004-02-19 22:34:13 +00:00
										 |  |  |     if (!s->is_mpeg2) { | 
					
						
							| 
									
										
										
										
											2004-10-01 20:05:04 +00:00
										 |  |  |         put_byte(pb, 0x0f); | 
					
						
							|  |  |  |         packet_bytes -= 7; | 
					
						
							| 
									
										
										
										
											2004-02-19 22:34:13 +00:00
										 |  |  |     } else | 
					
						
							| 
									
										
										
										
											2004-10-01 20:05:04 +00:00
										 |  |  |         packet_bytes -= 6; | 
					
						
							| 
									
										
										
										
											2004-02-19 22:34:13 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     for(i=0;i<packet_bytes;i++) | 
					
						
							|  |  |  |         put_byte(pb, 0xff); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-10-03 02:42:01 +00:00
										 |  |  | static int get_nb_frames(AVFormatContext *ctx, StreamInfo *stream, int len){ | 
					
						
							|  |  |  |     int nb_frames=0; | 
					
						
							|  |  |  |     PacketDesc *pkt_desc= stream->premux_packet; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     while(len>0){  | 
					
						
							|  |  |  |         if(pkt_desc->size == pkt_desc->unwritten_size) | 
					
						
							|  |  |  |             nb_frames++; | 
					
						
							|  |  |  |         len -= pkt_desc->unwritten_size; | 
					
						
							|  |  |  |         pkt_desc= pkt_desc->next; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return nb_frames; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2004-02-19 22:34:13 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-07-22 14:18:56 +00:00
										 |  |  | /* flush the packet on stream stream_index */ | 
					
						
							| 
									
										
										
										
											2004-10-03 02:42:01 +00:00
										 |  |  | static int flush_packet(AVFormatContext *ctx, int stream_index,  | 
					
						
							|  |  |  |                          int64_t pts, int64_t dts, int64_t scr, int trailer_size) | 
					
						
							| 
									
										
										
										
											2001-07-22 14:18:56 +00:00
										 |  |  | { | 
					
						
							|  |  |  |     MpegMuxContext *s = ctx->priv_data; | 
					
						
							|  |  |  |     StreamInfo *stream = ctx->streams[stream_index]->priv_data; | 
					
						
							| 
									
										
										
										
											2003-02-11 16:35:48 +00:00
										 |  |  |     uint8_t *buf_ptr; | 
					
						
							| 
									
										
										
										
											2003-12-16 11:25:30 +00:00
										 |  |  |     int size, payload_size, startcode, id, stuffing_size, i, header_len; | 
					
						
							|  |  |  |     int packet_size; | 
					
						
							| 
									
										
										
										
											2003-02-11 16:35:48 +00:00
										 |  |  |     uint8_t buffer[128]; | 
					
						
							| 
									
										
										
										
											2004-02-19 22:34:13 +00:00
										 |  |  |     int zero_trail_bytes = 0; | 
					
						
							|  |  |  |     int pad_packet_bytes = 0; | 
					
						
							| 
									
										
										
										
											2004-04-26 22:16:06 +00:00
										 |  |  |     int pes_flags; | 
					
						
							|  |  |  |     int general_pack = 0;  /*"general" pack without data specific to one stream?*/ | 
					
						
							| 
									
										
										
										
											2004-10-03 02:42:01 +00:00
										 |  |  |     int nb_frames; | 
					
						
							| 
									
										
										
										
											2002-05-12 21:38:54 +00:00
										 |  |  |      | 
					
						
							| 
									
										
										
										
											2001-07-22 14:18:56 +00:00
										 |  |  |     id = stream->id; | 
					
						
							| 
									
										
										
										
											2003-12-09 18:06:18 +00:00
										 |  |  |      | 
					
						
							| 
									
										
										
										
											2001-07-22 14:18:56 +00:00
										 |  |  | #if 0
 | 
					
						
							|  |  |  |     printf("packet ID=%2x PTS=%0.3f\n",  | 
					
						
							| 
									
										
										
										
											2003-12-09 18:06:18 +00:00
										 |  |  |            id, pts / 90000.0); | 
					
						
							| 
									
										
										
										
											2001-07-22 14:18:56 +00:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     buf_ptr = buffer; | 
					
						
							| 
									
										
										
										
											2004-02-19 22:34:13 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-10-03 02:42:01 +00:00
										 |  |  |     if ((s->packet_number % s->pack_header_freq) == 0 || s->last_scr != scr) { | 
					
						
							| 
									
										
										
										
											2001-07-22 14:18:56 +00:00
										 |  |  |         /* output pack and systems header if needed */ | 
					
						
							| 
									
										
										
										
											2003-12-09 18:06:18 +00:00
										 |  |  |         size = put_pack_header(ctx, buf_ptr, scr); | 
					
						
							| 
									
										
										
										
											2001-07-22 14:18:56 +00:00
										 |  |  |         buf_ptr += size; | 
					
						
							| 
									
										
										
										
											2004-10-03 02:42:01 +00:00
										 |  |  |         s->last_scr= scr; | 
					
						
							| 
									
										
										
										
											2004-02-19 22:34:13 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         if (s->is_vcd) { | 
					
						
							|  |  |  |             /* there is exactly one system header for each stream in a VCD MPEG,
 | 
					
						
							|  |  |  |                One in the very first video packet and one in the very first | 
					
						
							|  |  |  |                audio packet (see VCD standard p. IV-7 and IV-8).*/ | 
					
						
							|  |  |  |              | 
					
						
							|  |  |  |             if (stream->packet_number==0) { | 
					
						
							|  |  |  |                 size = put_system_header(ctx, buf_ptr, id); | 
					
						
							|  |  |  |                 buf_ptr += size; | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2004-11-23 22:25:12 +00:00
										 |  |  |         } else if (s->is_dvd) { | 
					
						
							|  |  |  |             if (stream->align_iframe || s->packet_number == 0){ | 
					
						
							|  |  |  |                 int bytes_to_iframe; | 
					
						
							|  |  |  |                 int PES_bytes_to_fill; | 
					
						
							|  |  |  |                 if (stream->fifo_iframe_ptr >= stream->fifo.rptr) { | 
					
						
							|  |  |  |                     bytes_to_iframe = stream->fifo_iframe_ptr - stream->fifo.rptr; | 
					
						
							|  |  |  |                 } else { | 
					
						
							|  |  |  |                     bytes_to_iframe = (stream->fifo.end - stream->fifo.rptr) + (stream->fifo_iframe_ptr - stream->fifo.buffer); | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |                 PES_bytes_to_fill = s->packet_size - size - 10; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 if (pts != AV_NOPTS_VALUE) { | 
					
						
							|  |  |  |                     if (dts != pts) | 
					
						
							|  |  |  |                         PES_bytes_to_fill -= 5 + 5; | 
					
						
							|  |  |  |                     else | 
					
						
							|  |  |  |                         PES_bytes_to_fill -= 5; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 if (bytes_to_iframe == 0 || s->packet_number == 0) { | 
					
						
							|  |  |  |                     size = put_system_header(ctx, buf_ptr, 0); | 
					
						
							|  |  |  |                     buf_ptr += size; | 
					
						
							|  |  |  |                     size = buf_ptr - buffer; | 
					
						
							|  |  |  |                     put_buffer(&ctx->pb, buffer, size); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                     put_be32(&ctx->pb, PRIVATE_STREAM_2); | 
					
						
							|  |  |  |                     put_be16(&ctx->pb, 0x03d4);         // length
 | 
					
						
							|  |  |  |                     put_byte(&ctx->pb, 0x00);           // substream ID, 00=PCI
 | 
					
						
							|  |  |  |                     for (i = 0; i < 979; i++) | 
					
						
							|  |  |  |                         put_byte(&ctx->pb, 0x00); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                     put_be32(&ctx->pb, PRIVATE_STREAM_2); | 
					
						
							|  |  |  |                     put_be16(&ctx->pb, 0x03fa);         // length
 | 
					
						
							|  |  |  |                     put_byte(&ctx->pb, 0x01);           // substream ID, 01=DSI
 | 
					
						
							|  |  |  |                     for (i = 0; i < 1017; i++) | 
					
						
							|  |  |  |                         put_byte(&ctx->pb, 0x00); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                     memset(buffer, 0, 128); | 
					
						
							|  |  |  |                     buf_ptr = buffer; | 
					
						
							|  |  |  |                     s->packet_number++; | 
					
						
							|  |  |  |                     stream->align_iframe = 0; | 
					
						
							|  |  |  |                     scr += s->packet_size*90000LL / (s->mux_rate*50LL); //FIXME rounding and first few bytes of each packet
 | 
					
						
							|  |  |  |                     size = put_pack_header(ctx, buf_ptr, scr); | 
					
						
							|  |  |  |                     s->last_scr= scr; | 
					
						
							|  |  |  |                     buf_ptr += size; | 
					
						
							|  |  |  |                     /* GOP Start */ | 
					
						
							|  |  |  |                 } else if (bytes_to_iframe < PES_bytes_to_fill) { | 
					
						
							|  |  |  |                     pad_packet_bytes = PES_bytes_to_fill - bytes_to_iframe; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2004-02-19 22:34:13 +00:00
										 |  |  |         } else { | 
					
						
							|  |  |  |             if ((s->packet_number % s->system_header_freq) == 0) { | 
					
						
							|  |  |  |                 size = put_system_header(ctx, buf_ptr, 0); | 
					
						
							|  |  |  |                 buf_ptr += size; | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2001-07-22 14:18:56 +00:00
										 |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     size = buf_ptr - buffer; | 
					
						
							|  |  |  |     put_buffer(&ctx->pb, buffer, size); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-02-19 22:34:13 +00:00
										 |  |  |     packet_size = s->packet_size - size; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (s->is_vcd && id == AUDIO_ID) | 
					
						
							|  |  |  |         /* The VCD standard demands that 20 zero bytes follow
 | 
					
						
							|  |  |  |            each audio pack (see standard p. IV-8).*/ | 
					
						
							|  |  |  |         zero_trail_bytes += 20; | 
					
						
							|  |  |  |              | 
					
						
							| 
									
										
										
										
											2004-04-26 22:16:06 +00:00
										 |  |  |     if ((s->is_vcd && stream->packet_number==0) | 
					
						
							|  |  |  |         || (s->is_svcd && s->packet_number==0)) { | 
					
						
							|  |  |  |         /* for VCD the first pack of each stream contains only the pack header,
 | 
					
						
							| 
									
										
										
										
											2004-02-19 22:34:13 +00:00
										 |  |  |            the system header and lots of padding (see VCD standard p. IV-6). | 
					
						
							|  |  |  |            In the case of an audio pack, 20 zero bytes are also added at | 
					
						
							|  |  |  |            the end.*/ | 
					
						
							| 
									
										
										
										
											2004-04-26 22:16:06 +00:00
										 |  |  |         /* For SVCD we fill the very first pack to increase compatibility with
 | 
					
						
							|  |  |  |            some DVD players. Not mandated by the standard.*/ | 
					
						
							|  |  |  |         if (s->is_svcd) | 
					
						
							|  |  |  |             general_pack = 1;    /* the system header refers to both streams and no stream data*/ | 
					
						
							| 
									
										
										
										
											2004-02-19 22:34:13 +00:00
										 |  |  |         pad_packet_bytes = packet_size - zero_trail_bytes; | 
					
						
							| 
									
										
										
										
											2003-12-09 18:06:18 +00:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-02-19 22:34:13 +00:00
										 |  |  |     packet_size -= pad_packet_bytes + zero_trail_bytes; | 
					
						
							| 
									
										
										
										
											2003-12-16 11:25:30 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-02-19 22:34:13 +00:00
										 |  |  |     if (packet_size > 0) { | 
					
						
							| 
									
										
										
										
											2001-07-22 14:18:56 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-02-19 22:34:13 +00:00
										 |  |  |         /* packet header size */ | 
					
						
							|  |  |  |         packet_size -= 6; | 
					
						
							|  |  |  |          | 
					
						
							|  |  |  |         /* packet header */ | 
					
						
							|  |  |  |         if (s->is_mpeg2) { | 
					
						
							|  |  |  |             header_len = 3; | 
					
						
							| 
									
										
										
										
											2004-04-26 22:16:06 +00:00
										 |  |  |             if (stream->packet_number==0) | 
					
						
							|  |  |  |                 header_len += 3; /* PES extension */ | 
					
						
							|  |  |  |             header_len += 1; /* obligatory stuffing byte */ | 
					
						
							| 
									
										
										
										
											2004-02-19 22:34:13 +00:00
										 |  |  |         } else { | 
					
						
							|  |  |  |             header_len = 0; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         if (pts != AV_NOPTS_VALUE) { | 
					
						
							|  |  |  |             if (dts != pts) | 
					
						
							|  |  |  |                 header_len += 5 + 5; | 
					
						
							|  |  |  |             else | 
					
						
							|  |  |  |                 header_len += 5; | 
					
						
							|  |  |  |         } else { | 
					
						
							|  |  |  |             if (!s->is_mpeg2) | 
					
						
							|  |  |  |                 header_len++; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2004-02-01 13:06:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-02-19 22:34:13 +00:00
										 |  |  |         payload_size = packet_size - header_len; | 
					
						
							|  |  |  |         if (id < 0xc0) { | 
					
						
							|  |  |  |             startcode = PRIVATE_STREAM_1; | 
					
						
							|  |  |  |             payload_size -= 4; | 
					
						
							|  |  |  |             if (id >= 0xa0) | 
					
						
							|  |  |  |                 payload_size -= 3; | 
					
						
							|  |  |  |         } else { | 
					
						
							|  |  |  |             startcode = 0x100 + id; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2002-10-15 10:22:23 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-10-03 02:42:01 +00:00
										 |  |  |         stuffing_size = payload_size - fifo_size(&stream->fifo, stream->fifo.rptr); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // first byte doesnt fit -> reset pts/dts + stuffing
 | 
					
						
							|  |  |  |         if(payload_size <= trailer_size && pts != AV_NOPTS_VALUE){ | 
					
						
							|  |  |  |             int timestamp_len=0; | 
					
						
							|  |  |  |             if(dts != pts)  | 
					
						
							|  |  |  |                 timestamp_len += 5; | 
					
						
							|  |  |  |             if(pts != AV_NOPTS_VALUE) | 
					
						
							|  |  |  |                 timestamp_len += s->is_mpeg2 ? 5 : 4; | 
					
						
							|  |  |  |             pts=dts= AV_NOPTS_VALUE; | 
					
						
							|  |  |  |             header_len -= timestamp_len; | 
					
						
							| 
									
										
										
										
											2004-11-23 22:25:12 +00:00
										 |  |  |             if (s->is_dvd && stream->align_iframe) { | 
					
						
							|  |  |  |                 pad_packet_bytes += timestamp_len; | 
					
						
							|  |  |  |                 packet_size -= timestamp_len; | 
					
						
							|  |  |  |             } else { | 
					
						
							|  |  |  |                 payload_size += timestamp_len; | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2004-10-03 02:42:01 +00:00
										 |  |  |             stuffing_size += timestamp_len; | 
					
						
							|  |  |  |             if(payload_size > trailer_size) | 
					
						
							|  |  |  |                 stuffing_size += payload_size - trailer_size; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-11-23 22:25:12 +00:00
										 |  |  |         if (pad_packet_bytes > 0 && pad_packet_bytes <= 7) { // can't use padding, so use stuffing
 | 
					
						
							|  |  |  |             packet_size += pad_packet_bytes; | 
					
						
							|  |  |  |             payload_size += pad_packet_bytes; // undo the previous adjustment
 | 
					
						
							|  |  |  |             if (stuffing_size < 0) { | 
					
						
							|  |  |  |                 stuffing_size = pad_packet_bytes; | 
					
						
							|  |  |  |             } else { | 
					
						
							|  |  |  |                 stuffing_size += pad_packet_bytes; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             pad_packet_bytes = 0; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-02-19 22:34:13 +00:00
										 |  |  |         if (stuffing_size < 0) | 
					
						
							|  |  |  |             stuffing_size = 0; | 
					
						
							| 
									
										
										
										
											2004-04-26 22:16:06 +00:00
										 |  |  |         if (stuffing_size > 16) {    /*<=16 for MPEG-1, <=32 for MPEG-2*/ | 
					
						
							|  |  |  |             pad_packet_bytes += stuffing_size; | 
					
						
							|  |  |  |             packet_size -= stuffing_size; | 
					
						
							|  |  |  |             payload_size -= stuffing_size; | 
					
						
							|  |  |  |             stuffing_size = 0; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2004-10-03 02:42:01 +00:00
										 |  |  |          | 
					
						
							|  |  |  |         nb_frames= get_nb_frames(ctx, stream, payload_size - stuffing_size); | 
					
						
							| 
									
										
										
										
											2004-04-26 22:16:06 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-02-19 22:34:13 +00:00
										 |  |  |         put_be32(&ctx->pb, startcode); | 
					
						
							| 
									
										
										
										
											2003-12-09 18:06:18 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-02-19 22:34:13 +00:00
										 |  |  |         put_be16(&ctx->pb, packet_size); | 
					
						
							|  |  |  |          | 
					
						
							|  |  |  |         if (!s->is_mpeg2) | 
					
						
							|  |  |  |             for(i=0;i<stuffing_size;i++) | 
					
						
							|  |  |  |                 put_byte(&ctx->pb, 0xff); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (s->is_mpeg2) { | 
					
						
							|  |  |  |             put_byte(&ctx->pb, 0x80); /* mpeg2 id */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-04-26 22:16:06 +00:00
										 |  |  |             pes_flags=0; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-02-19 22:34:13 +00:00
										 |  |  |             if (pts != AV_NOPTS_VALUE) { | 
					
						
							| 
									
										
										
										
											2004-04-26 22:16:06 +00:00
										 |  |  |                 pes_flags |= 0x80; | 
					
						
							|  |  |  |                 if (dts != pts) | 
					
						
							|  |  |  |                     pes_flags |= 0x40; | 
					
						
							| 
									
										
										
										
											2003-12-09 18:06:18 +00:00
										 |  |  |             } | 
					
						
							| 
									
										
										
										
											2004-04-26 22:16:06 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |             /* Both the MPEG-2 and the SVCD standards demand that the
 | 
					
						
							|  |  |  |                P-STD_buffer_size field be included in the first packet of | 
					
						
							|  |  |  |                every stream. (see SVCD standard p. 26 V.2.3.1 and V.2.3.2 | 
					
						
							|  |  |  |                and MPEG-2 standard 2.7.7) */ | 
					
						
							|  |  |  |             if (stream->packet_number == 0) | 
					
						
							|  |  |  |                 pes_flags |= 0x01; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             put_byte(&ctx->pb, pes_flags); /* flags */ | 
					
						
							|  |  |  |             put_byte(&ctx->pb, header_len - 3 + stuffing_size); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if (pes_flags & 0x80)  /*write pts*/ | 
					
						
							|  |  |  |                 put_timestamp(&ctx->pb, (pes_flags & 0x40) ? 0x03 : 0x02, pts); | 
					
						
							|  |  |  |             if (pes_flags & 0x40)  /*write dts*/ | 
					
						
							|  |  |  |                 put_timestamp(&ctx->pb, 0x01, dts); | 
					
						
							|  |  |  |              | 
					
						
							|  |  |  |             if (pes_flags & 0x01) {  /*write pes extension*/ | 
					
						
							|  |  |  |                 put_byte(&ctx->pb, 0x10); /* flags */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 /* P-STD buffer info */                 | 
					
						
							|  |  |  |                 if (id == AUDIO_ID) | 
					
						
							|  |  |  |                     put_be16(&ctx->pb, 0x4000 | stream->max_buffer_size/128); | 
					
						
							|  |  |  |                 else | 
					
						
							|  |  |  |                     put_be16(&ctx->pb, 0x6000 | stream->max_buffer_size/1024); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-12-09 18:06:18 +00:00
										 |  |  |         } else { | 
					
						
							| 
									
										
										
										
											2004-02-19 22:34:13 +00:00
										 |  |  |             if (pts != AV_NOPTS_VALUE) { | 
					
						
							|  |  |  |                 if (dts != pts) { | 
					
						
							|  |  |  |                     put_timestamp(&ctx->pb, 0x03, pts); | 
					
						
							|  |  |  |                     put_timestamp(&ctx->pb, 0x01, dts); | 
					
						
							|  |  |  |                 } else { | 
					
						
							|  |  |  |                     put_timestamp(&ctx->pb, 0x02, pts); | 
					
						
							|  |  |  |                 } | 
					
						
							| 
									
										
										
										
											2003-12-09 18:06:18 +00:00
										 |  |  |             } else { | 
					
						
							| 
									
										
										
										
											2004-02-19 22:34:13 +00:00
										 |  |  |                 put_byte(&ctx->pb, 0x0f); | 
					
						
							| 
									
										
										
										
											2003-12-09 18:06:18 +00:00
										 |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2001-07-22 14:18:56 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-05-25 23:06:00 +00:00
										 |  |  |         if (s->is_mpeg2) { | 
					
						
							|  |  |  |             /* special stuffing byte that is always written
 | 
					
						
							|  |  |  |                to prevent accidental generation of start codes. */ | 
					
						
							|  |  |  |             put_byte(&ctx->pb, 0xff); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             for(i=0;i<stuffing_size;i++) | 
					
						
							|  |  |  |                 put_byte(&ctx->pb, 0xff); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-02-19 22:34:13 +00:00
										 |  |  |         if (startcode == PRIVATE_STREAM_1) { | 
					
						
							|  |  |  |             put_byte(&ctx->pb, id); | 
					
						
							|  |  |  |             if (id >= 0xa0) { | 
					
						
							|  |  |  |                 /* LPCM (XXX: check nb_frames) */ | 
					
						
							|  |  |  |                 put_byte(&ctx->pb, 7); | 
					
						
							|  |  |  |                 put_be16(&ctx->pb, 4); /* skip 3 header bytes */ | 
					
						
							|  |  |  |                 put_byte(&ctx->pb, stream->lpcm_header[0]); | 
					
						
							|  |  |  |                 put_byte(&ctx->pb, stream->lpcm_header[1]); | 
					
						
							|  |  |  |                 put_byte(&ctx->pb, stream->lpcm_header[2]); | 
					
						
							|  |  |  |             } else { | 
					
						
							|  |  |  |                 /* AC3 */ | 
					
						
							| 
									
										
										
										
											2004-10-03 02:42:01 +00:00
										 |  |  |                 put_byte(&ctx->pb, nb_frames); | 
					
						
							|  |  |  |                 put_be16(&ctx->pb, trailer_size+1); | 
					
						
							| 
									
										
										
										
											2004-02-19 22:34:13 +00:00
										 |  |  |             } | 
					
						
							| 
									
										
										
										
											2001-07-22 14:18:56 +00:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2004-02-19 22:34:13 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         /* output data */ | 
					
						
							| 
									
										
										
										
											2004-10-03 02:42:01 +00:00
										 |  |  |         if(put_fifo(&ctx->pb, &stream->fifo, payload_size - stuffing_size, &stream->fifo.rptr) < 0) | 
					
						
							|  |  |  |             return -1; | 
					
						
							|  |  |  |     }else{ | 
					
						
							|  |  |  |         payload_size= | 
					
						
							|  |  |  |         stuffing_size= 0; | 
					
						
							| 
									
										
										
										
											2001-07-22 14:18:56 +00:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-02-19 22:34:13 +00:00
										 |  |  |     if (pad_packet_bytes > 0) | 
					
						
							|  |  |  |         put_padding_packet(ctx,&ctx->pb, pad_packet_bytes);     | 
					
						
							| 
									
										
										
										
											2004-02-01 13:06:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-02-19 22:34:13 +00:00
										 |  |  |     for(i=0;i<zero_trail_bytes;i++) | 
					
						
							|  |  |  |         put_byte(&ctx->pb, 0x00); | 
					
						
							|  |  |  |          | 
					
						
							| 
									
										
										
										
											2001-07-22 14:18:56 +00:00
										 |  |  |     put_flush_packet(&ctx->pb); | 
					
						
							|  |  |  |      | 
					
						
							|  |  |  |     s->packet_number++; | 
					
						
							| 
									
										
										
										
											2004-04-26 22:16:06 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     /* only increase the stream packet number if this pack actually contains
 | 
					
						
							|  |  |  |        something that is specific to this stream! I.e. a dedicated header | 
					
						
							|  |  |  |        or some data.*/ | 
					
						
							|  |  |  |     if (!general_pack) | 
					
						
							|  |  |  |         stream->packet_number++; | 
					
						
							| 
									
										
										
										
											2004-10-03 02:42:01 +00:00
										 |  |  |      | 
					
						
							|  |  |  |     return payload_size - stuffing_size; | 
					
						
							| 
									
										
										
										
											2001-07-22 14:18:56 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-02-19 22:34:13 +00:00
										 |  |  | static void put_vcd_padding_sector(AVFormatContext *ctx) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     /* There are two ways to do this padding: writing a sector/pack
 | 
					
						
							|  |  |  |        of 0 values, or writing an MPEG padding pack. Both seem to | 
					
						
							|  |  |  |        work with most decoders, BUT the VCD standard only allows a 0-sector | 
					
						
							|  |  |  |        (see standard p. IV-4, IV-5). | 
					
						
							|  |  |  |        So a 0-sector it is...*/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     MpegMuxContext *s = ctx->priv_data; | 
					
						
							|  |  |  |     int i; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for(i=0;i<s->packet_size;i++) | 
					
						
							|  |  |  |         put_byte(&ctx->pb, 0); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     s->vcd_padding_bytes_written += s->packet_size; | 
					
						
							|  |  |  |          | 
					
						
							|  |  |  |     put_flush_packet(&ctx->pb); | 
					
						
							|  |  |  |      | 
					
						
							|  |  |  |     /* increasing the packet number is correct. The SCR of the following packs
 | 
					
						
							|  |  |  |        is calculated from the packet_number and it has to include the padding | 
					
						
							|  |  |  |        sector (it represents the sector index, not the MPEG pack index) | 
					
						
							|  |  |  |        (see VCD standard p. IV-6)*/ | 
					
						
							|  |  |  |     s->packet_number++; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-02-24 19:08:50 +00:00
										 |  |  | #if 0 /* unused, remove? */
 | 
					
						
							| 
									
										
										
										
											2004-10-03 02:57:42 +00:00
										 |  |  | static int64_t get_vcd_scr(AVFormatContext *ctx,int stream_index,int64_t pts) | 
					
						
							| 
									
										
										
										
											2004-02-19 22:34:13 +00:00
										 |  |  | { | 
					
						
							|  |  |  |     MpegMuxContext *s = ctx->priv_data; | 
					
						
							|  |  |  |     int64_t scr; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         /* Since the data delivery rate is constant, SCR is computed
 | 
					
						
							|  |  |  |            using the formula C + i * 1200 where C is the start constant | 
					
						
							|  |  |  |            and i is the pack index. | 
					
						
							|  |  |  |            It is recommended that SCR 0 is at the beginning of the VCD front | 
					
						
							|  |  |  |            margin (a sequence of empty Form 2 sectors on the CD). | 
					
						
							|  |  |  |            It is recommended that the front margin is 30 sectors long, so | 
					
						
							|  |  |  |            we use C = 30*1200 = 36000 | 
					
						
							|  |  |  |            (Note that even if the front margin is not 30 sectors the file | 
					
						
							|  |  |  |            will still be correct according to the standard. It just won't have | 
					
						
							|  |  |  |            the "recommended" value).*/ | 
					
						
							|  |  |  |         scr = 36000 + s->packet_number * 1200; | 
					
						
							| 
									
										
										
										
											2004-04-26 22:16:06 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-02-19 22:34:13 +00:00
										 |  |  |     return scr; | 
					
						
							|  |  |  | }     | 
					
						
							| 
									
										
										
										
											2005-02-24 19:08:50 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2004-02-19 22:34:13 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-10-03 02:42:01 +00:00
										 |  |  | static int remove_decoded_packets(AVFormatContext *ctx, int64_t scr){ | 
					
						
							|  |  |  | //    MpegMuxContext *s = ctx->priv_data;
 | 
					
						
							|  |  |  |     int i; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for(i=0; i<ctx->nb_streams; i++){ | 
					
						
							|  |  |  |         AVStream *st = ctx->streams[i]; | 
					
						
							|  |  |  |         StreamInfo *stream = st->priv_data; | 
					
						
							|  |  |  |         PacketDesc *pkt_desc= stream->predecode_packet; | 
					
						
							|  |  |  |          | 
					
						
							|  |  |  |         while(pkt_desc && scr > pkt_desc->dts){ //FIXME > vs >=
 | 
					
						
							|  |  |  |             if(stream->buffer_index < pkt_desc->size ||  | 
					
						
							|  |  |  |                stream->predecode_packet == stream->premux_packet){ | 
					
						
							|  |  |  |                 av_log(ctx, AV_LOG_ERROR, "buffer underflow\n"); | 
					
						
							|  |  |  |                 break; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             stream->buffer_index -= pkt_desc->size; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             stream->predecode_packet= pkt_desc->next; | 
					
						
							|  |  |  |             av_freep(&pkt_desc); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |      | 
					
						
							|  |  |  |     return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int output_packet(AVFormatContext *ctx, int flush){ | 
					
						
							|  |  |  |     MpegMuxContext *s = ctx->priv_data; | 
					
						
							|  |  |  |     AVStream *st; | 
					
						
							|  |  |  |     StreamInfo *stream; | 
					
						
							|  |  |  |     int i, avail_space, es_size, trailer_size; | 
					
						
							|  |  |  |     int best_i= -1; | 
					
						
							|  |  |  |     int best_score= INT_MIN; | 
					
						
							|  |  |  |     int ignore_constraints=0; | 
					
						
							|  |  |  |     int64_t scr= s->last_scr; | 
					
						
							| 
									
										
										
										
											2004-10-03 11:16:40 +00:00
										 |  |  |     PacketDesc *timestamp_packet; | 
					
						
							| 
									
										
										
										
											2004-10-16 21:27:42 +00:00
										 |  |  |     const int64_t max_delay= av_rescale(ctx->max_delay, 90000, AV_TIME_BASE); | 
					
						
							| 
									
										
										
										
											2004-10-03 02:42:01 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | retry: | 
					
						
							|  |  |  |     for(i=0; i<ctx->nb_streams; i++){ | 
					
						
							|  |  |  |         AVStream *st = ctx->streams[i]; | 
					
						
							|  |  |  |         StreamInfo *stream = st->priv_data; | 
					
						
							|  |  |  |         const int avail_data=  fifo_size(&stream->fifo, stream->fifo.rptr); | 
					
						
							|  |  |  |         const int space= stream->max_buffer_size - stream->buffer_index; | 
					
						
							|  |  |  |         int rel_space= 1024*space / stream->max_buffer_size; | 
					
						
							| 
									
										
										
										
											2004-10-16 21:27:42 +00:00
										 |  |  |         PacketDesc *next_pkt= stream->premux_packet; | 
					
						
							| 
									
										
										
										
											2004-10-03 02:42:01 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         if(s->packet_size > avail_data && !flush) | 
					
						
							|  |  |  |             return 0; | 
					
						
							|  |  |  |         if(avail_data==0) | 
					
						
							|  |  |  |             continue; | 
					
						
							|  |  |  |         assert(avail_data>0); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if(space < s->packet_size && !ignore_constraints) | 
					
						
							|  |  |  |             continue; | 
					
						
							|  |  |  |              | 
					
						
							| 
									
										
										
										
											2004-10-16 21:27:42 +00:00
										 |  |  |         if(next_pkt && next_pkt->dts - scr > max_delay) | 
					
						
							|  |  |  |             continue; | 
					
						
							|  |  |  |              | 
					
						
							| 
									
										
										
										
											2004-10-03 02:42:01 +00:00
										 |  |  |         if(rel_space > best_score){ | 
					
						
							|  |  |  |             best_score= rel_space; | 
					
						
							|  |  |  |             best_i = i; | 
					
						
							|  |  |  |             avail_space= space; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |      | 
					
						
							|  |  |  |     if(best_i < 0){ | 
					
						
							|  |  |  |         int64_t best_dts= INT64_MAX; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         for(i=0; i<ctx->nb_streams; i++){ | 
					
						
							|  |  |  |             AVStream *st = ctx->streams[i]; | 
					
						
							|  |  |  |             StreamInfo *stream = st->priv_data; | 
					
						
							|  |  |  |             PacketDesc *pkt_desc= stream->predecode_packet; | 
					
						
							|  |  |  |             if(pkt_desc && pkt_desc->dts < best_dts) | 
					
						
							|  |  |  |                 best_dts= pkt_desc->dts; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #if 0
 | 
					
						
							|  |  |  |         av_log(ctx, AV_LOG_DEBUG, "bumping scr, scr:%f, dts:%f\n",  | 
					
						
							|  |  |  |                scr/90000.0, best_dts/90000.0); | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  |         if(best_dts == INT64_MAX) | 
					
						
							|  |  |  |             return 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if(scr >= best_dts+1 && !ignore_constraints){ | 
					
						
							|  |  |  |             av_log(ctx, AV_LOG_ERROR, "packet too large, ignoring buffer limits to mux it\n"); | 
					
						
							|  |  |  |             ignore_constraints= 1; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         scr= FFMAX(best_dts+1, scr); | 
					
						
							|  |  |  |         if(remove_decoded_packets(ctx, scr) < 0) | 
					
						
							|  |  |  |             return -1; | 
					
						
							|  |  |  |         goto retry; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     assert(best_i >= 0); | 
					
						
							|  |  |  |      | 
					
						
							|  |  |  |     st = ctx->streams[best_i]; | 
					
						
							|  |  |  |     stream = st->priv_data; | 
					
						
							|  |  |  |      | 
					
						
							|  |  |  |     assert(fifo_size(&stream->fifo, stream->fifo.rptr) > 0); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     assert(avail_space >= s->packet_size || ignore_constraints); | 
					
						
							|  |  |  |      | 
					
						
							| 
									
										
										
										
											2004-10-03 11:16:40 +00:00
										 |  |  |     timestamp_packet= stream->premux_packet; | 
					
						
							|  |  |  |     if(timestamp_packet->unwritten_size == timestamp_packet->size){ | 
					
						
							| 
									
										
										
										
											2004-10-03 02:42:01 +00:00
										 |  |  |         trailer_size= 0; | 
					
						
							| 
									
										
										
										
											2004-10-03 11:16:40 +00:00
										 |  |  |     }else{ | 
					
						
							|  |  |  |         trailer_size= timestamp_packet->unwritten_size; | 
					
						
							|  |  |  |         timestamp_packet= timestamp_packet->next; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2004-10-03 02:42:01 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-10-03 11:16:40 +00:00
										 |  |  |     if(timestamp_packet){ | 
					
						
							| 
									
										
										
										
											2004-10-06 22:29:30 +00:00
										 |  |  | //av_log(ctx, AV_LOG_DEBUG, "dts:%f pts:%f scr:%f stream:%d\n", timestamp_packet->dts/90000.0, timestamp_packet->pts/90000.0, scr/90000.0, best_i);
 | 
					
						
							| 
									
										
										
										
											2004-10-03 11:16:40 +00:00
										 |  |  |         es_size= flush_packet(ctx, best_i, timestamp_packet->pts, timestamp_packet->dts, scr, trailer_size); | 
					
						
							|  |  |  |     }else{ | 
					
						
							|  |  |  |         assert(fifo_size(&stream->fifo, stream->fifo.rptr) == trailer_size); | 
					
						
							|  |  |  |         es_size= flush_packet(ctx, best_i, AV_NOPTS_VALUE, AV_NOPTS_VALUE, scr, trailer_size); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2004-10-03 02:42:01 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if (s->is_vcd) { | 
					
						
							|  |  |  |         /* Write one or more padding sectors, if necessary, to reach
 | 
					
						
							|  |  |  |            the constant overall bitrate.*/ | 
					
						
							|  |  |  |         int vcd_pad_bytes; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-10-03 02:57:42 +00:00
										 |  |  |         while((vcd_pad_bytes = get_vcd_padding_size(ctx,stream->premux_packet->pts) ) >= s->packet_size){ //FIXME pts cannot be correct here
 | 
					
						
							| 
									
										
										
										
											2004-10-03 02:42:01 +00:00
										 |  |  |             put_vcd_padding_sector(ctx); | 
					
						
							|  |  |  |             s->last_scr += s->packet_size*90000LL / (s->mux_rate*50LL); //FIXME rounding and first few bytes of each packet
 | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |      | 
					
						
							|  |  |  |     stream->buffer_index += es_size; | 
					
						
							|  |  |  |     s->last_scr += s->packet_size*90000LL / (s->mux_rate*50LL); //FIXME rounding and first few bytes of each packet
 | 
					
						
							|  |  |  |      | 
					
						
							|  |  |  |     while(stream->premux_packet && stream->premux_packet->unwritten_size <= es_size){ | 
					
						
							|  |  |  |         es_size -= stream->premux_packet->unwritten_size; | 
					
						
							|  |  |  |         stream->premux_packet= stream->premux_packet->next; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if(es_size) | 
					
						
							|  |  |  |         stream->premux_packet->unwritten_size -= es_size; | 
					
						
							|  |  |  |      | 
					
						
							|  |  |  |     if(remove_decoded_packets(ctx, s->last_scr) < 0) | 
					
						
							|  |  |  |         return -1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return 1; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2004-02-19 22:34:13 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-05-29 02:06:32 +00:00
										 |  |  | static int mpeg_mux_write_packet(AVFormatContext *ctx, AVPacket *pkt) | 
					
						
							| 
									
										
										
										
											2001-07-22 14:18:56 +00:00
										 |  |  | { | 
					
						
							|  |  |  |     MpegMuxContext *s = ctx->priv_data; | 
					
						
							| 
									
										
										
										
											2004-05-29 02:06:32 +00:00
										 |  |  |     int stream_index= pkt->stream_index; | 
					
						
							|  |  |  |     int size= pkt->size; | 
					
						
							|  |  |  |     uint8_t *buf= pkt->data; | 
					
						
							| 
									
										
										
										
											2001-07-22 14:18:56 +00:00
										 |  |  |     AVStream *st = ctx->streams[stream_index]; | 
					
						
							|  |  |  |     StreamInfo *stream = st->priv_data; | 
					
						
							| 
									
										
										
										
											2004-10-03 02:57:42 +00:00
										 |  |  |     int64_t pts, dts; | 
					
						
							| 
									
										
										
										
											2004-10-03 02:42:01 +00:00
										 |  |  |     PacketDesc *pkt_desc; | 
					
						
							| 
									
										
										
										
											2004-10-16 21:27:42 +00:00
										 |  |  |     const int preload= av_rescale(ctx->preload, 90000, AV_TIME_BASE); | 
					
						
							| 
									
										
										
										
											2004-11-21 03:37:33 +00:00
										 |  |  |     const int is_iframe = st->codec.codec_type == CODEC_TYPE_VIDEO && (pkt->flags & PKT_FLAG_KEY); | 
					
						
							| 
									
										
										
										
											2004-02-19 22:34:13 +00:00
										 |  |  |      | 
					
						
							| 
									
										
										
										
											2004-05-29 02:06:32 +00:00
										 |  |  |     pts= pkt->pts; | 
					
						
							|  |  |  |     dts= pkt->dts; | 
					
						
							| 
									
										
										
										
											2003-12-18 13:03:37 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-10-16 21:27:42 +00:00
										 |  |  |     if(pts != AV_NOPTS_VALUE) pts += preload; | 
					
						
							|  |  |  |     if(dts != AV_NOPTS_VALUE) dts += preload; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-10-07 01:55:34 +00:00
										 |  |  | //av_log(ctx, AV_LOG_DEBUG, "dts:%f pts:%f flags:%d stream:%d nopts:%d\n", dts/90000.0, pts/90000.0, pkt->flags, pkt->stream_index, pts != AV_NOPTS_VALUE);
 | 
					
						
							| 
									
										
										
										
											2004-10-03 02:42:01 +00:00
										 |  |  |     *stream->next_packet= | 
					
						
							|  |  |  |     pkt_desc= av_mallocz(sizeof(PacketDesc)); | 
					
						
							|  |  |  |     pkt_desc->pts= pts; | 
					
						
							|  |  |  |     pkt_desc->dts= dts; | 
					
						
							|  |  |  |     pkt_desc->unwritten_size= | 
					
						
							|  |  |  |     pkt_desc->size= size; | 
					
						
							|  |  |  |     if(!stream->predecode_packet) | 
					
						
							|  |  |  |         stream->predecode_packet= pkt_desc; | 
					
						
							|  |  |  |     stream->next_packet= &pkt_desc->next; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-12-05 02:46:00 +00:00
										 |  |  |     fifo_realloc(&stream->fifo, fifo_size(&stream->fifo, NULL) + size + 1); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-11-21 03:37:33 +00:00
										 |  |  |     if (s->is_dvd){ | 
					
						
							| 
									
										
										
										
											2005-02-09 03:00:50 +00:00
										 |  |  |         if (is_iframe && (s->packet_number == 0 || (pts - stream->vobu_start_pts >= 36000))) { // min VOBU length 0.4 seconds (mpucoder)
 | 
					
						
							| 
									
										
										
										
											2004-11-21 03:37:33 +00:00
										 |  |  |             stream->fifo_iframe_ptr = stream->fifo.wptr; | 
					
						
							|  |  |  |             stream->align_iframe = 1; | 
					
						
							| 
									
										
										
										
											2005-02-09 03:00:50 +00:00
										 |  |  |             stream->vobu_start_pts = pts; | 
					
						
							| 
									
										
										
										
											2004-11-21 03:37:33 +00:00
										 |  |  |         } else { | 
					
						
							|  |  |  |             stream->align_iframe = 0; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-10-03 02:42:01 +00:00
										 |  |  |     fifo_write(&stream->fifo, buf, size, &stream->fifo.wptr); | 
					
						
							| 
									
										
										
										
											2004-02-19 22:34:13 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-10-03 02:42:01 +00:00
										 |  |  |     for(;;){ | 
					
						
							|  |  |  |         int ret= output_packet(ctx, 0); | 
					
						
							| 
									
										
										
										
											2004-10-03 02:57:42 +00:00
										 |  |  |         if(ret<=0)  | 
					
						
							| 
									
										
										
										
											2004-10-03 02:42:01 +00:00
										 |  |  |             return ret; | 
					
						
							| 
									
										
										
										
											2003-12-16 11:25:30 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2001-07-22 14:18:56 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int mpeg_mux_end(AVFormatContext *ctx) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2004-10-03 02:42:01 +00:00
										 |  |  | //    MpegMuxContext *s = ctx->priv_data;
 | 
					
						
							| 
									
										
										
										
											2001-07-22 14:18:56 +00:00
										 |  |  |     StreamInfo *stream; | 
					
						
							|  |  |  |     int i; | 
					
						
							| 
									
										
										
										
											2004-10-03 02:42:01 +00:00
										 |  |  |      | 
					
						
							|  |  |  |     for(;;){ | 
					
						
							|  |  |  |         int ret= output_packet(ctx, 1); | 
					
						
							|  |  |  |         if(ret<0)  | 
					
						
							|  |  |  |             return ret; | 
					
						
							|  |  |  |         else if(ret==0) | 
					
						
							|  |  |  |             break; | 
					
						
							| 
									
										
										
										
											2001-07-22 14:18:56 +00:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-09-10 22:44:30 +00:00
										 |  |  |     /* End header according to MPEG1 systems standard. We do not write
 | 
					
						
							|  |  |  |        it as it is usually not needed by decoders and because it | 
					
						
							|  |  |  |        complicates MPEG stream concatenation. */ | 
					
						
							| 
									
										
										
										
											2002-05-12 21:38:54 +00:00
										 |  |  |     //put_be32(&ctx->pb, ISO_11172_END_CODE);
 | 
					
						
							|  |  |  |     //put_flush_packet(&ctx->pb);
 | 
					
						
							| 
									
										
										
										
											2003-09-09 19:32:52 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-10-03 02:42:01 +00:00
										 |  |  |     for(i=0;i<ctx->nb_streams;i++) { | 
					
						
							|  |  |  |         stream = ctx->streams[i]->priv_data; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         assert(fifo_size(&stream->fifo, stream->fifo.rptr) == 0); | 
					
						
							|  |  |  |         fifo_free(&stream->fifo); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2001-07-22 14:18:56 +00:00
										 |  |  |     return 0; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2003-10-14 04:15:53 +00:00
										 |  |  | #endif //CONFIG_ENCODERS
 | 
					
						
							| 
									
										
										
										
											2001-07-22 14:18:56 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | /*********************************************/ | 
					
						
							|  |  |  | /* demux code */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #define MAX_SYNC_SIZE 100000
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2002-05-20 16:29:40 +00:00
										 |  |  | static int mpegps_probe(AVProbeData *p) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2004-10-01 16:00:00 +00:00
										 |  |  |     int i; | 
					
						
							|  |  |  |     int size= FFMIN(20, p->buf_size); | 
					
						
							|  |  |  |     uint32_t code=0xFF; | 
					
						
							| 
									
										
										
										
											2002-05-20 16:29:40 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     /* we search the first start code. If it is a packet start code,
 | 
					
						
							|  |  |  |        then we decide it is mpeg ps. We do not send highest value to | 
					
						
							|  |  |  |        give a chance to mpegts */ | 
					
						
							| 
									
										
										
										
											2003-02-02 20:04:03 +00:00
										 |  |  |     /* NOTE: the search range was restricted to avoid too many false
 | 
					
						
							|  |  |  |        detections */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-10-01 16:00:00 +00:00
										 |  |  |     for (i = 0; i < size; i++) { | 
					
						
							|  |  |  |         code = (code << 8) | p->buf[i]; | 
					
						
							| 
									
										
										
										
											2003-07-10 09:04:04 +00:00
										 |  |  |         if ((code & 0xffffff00) == 0x100) { | 
					
						
							|  |  |  |             if (code == PACK_START_CODE || | 
					
						
							|  |  |  |                 code == SYSTEM_HEADER_START_CODE || | 
					
						
							|  |  |  |                 (code >= 0x1e0 && code <= 0x1ef) || | 
					
						
							|  |  |  |                 (code >= 0x1c0 && code <= 0x1df) || | 
					
						
							|  |  |  |                 code == PRIVATE_STREAM_2 || | 
					
						
							|  |  |  |                 code == PROGRAM_STREAM_MAP || | 
					
						
							|  |  |  |                 code == PRIVATE_STREAM_1 || | 
					
						
							|  |  |  |                 code == PADDING_STREAM) | 
					
						
							| 
									
										
										
										
											2003-09-01 18:30:02 +00:00
										 |  |  |                 return AVPROBE_SCORE_MAX - 2; | 
					
						
							| 
									
										
										
										
											2003-07-10 09:04:04 +00:00
										 |  |  |             else | 
					
						
							|  |  |  |                 return 0; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2002-05-20 16:29:40 +00:00
										 |  |  |     } | 
					
						
							|  |  |  |     return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-07-22 14:18:56 +00:00
										 |  |  | typedef struct MpegDemuxContext { | 
					
						
							|  |  |  |     int header_state; | 
					
						
							|  |  |  | } MpegDemuxContext; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-11-10 18:47:52 +00:00
										 |  |  | static int mpegps_read_header(AVFormatContext *s, | 
					
						
							|  |  |  |                               AVFormatParameters *ap) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     MpegDemuxContext *m = s->priv_data; | 
					
						
							|  |  |  |     m->header_state = 0xff; | 
					
						
							|  |  |  |     s->ctx_flags |= AVFMTCTX_NOHEADER; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* no need to do more */ | 
					
						
							|  |  |  |     return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int64_t get_pts(ByteIOContext *pb, int c) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     int64_t pts; | 
					
						
							|  |  |  |     int val; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (c < 0) | 
					
						
							|  |  |  |         c = get_byte(pb); | 
					
						
							|  |  |  |     pts = (int64_t)((c >> 1) & 0x07) << 30; | 
					
						
							|  |  |  |     val = get_be16(pb); | 
					
						
							|  |  |  |     pts |= (int64_t)(val >> 1) << 15; | 
					
						
							|  |  |  |     val = get_be16(pb); | 
					
						
							|  |  |  |     pts |= (int64_t)(val >> 1); | 
					
						
							|  |  |  |     return pts; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int find_next_start_code(ByteIOContext *pb, int *size_ptr,  | 
					
						
							|  |  |  |                                 uint32_t *header_state) | 
					
						
							| 
									
										
										
										
											2001-07-22 14:18:56 +00:00
										 |  |  | { | 
					
						
							|  |  |  |     unsigned int state, v; | 
					
						
							|  |  |  |     int val, n; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     state = *header_state; | 
					
						
							|  |  |  |     n = *size_ptr; | 
					
						
							|  |  |  |     while (n > 0) { | 
					
						
							|  |  |  |         if (url_feof(pb)) | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |         v = get_byte(pb); | 
					
						
							|  |  |  |         n--; | 
					
						
							|  |  |  |         if (state == 0x000001) { | 
					
						
							|  |  |  |             state = ((state << 8) | v) & 0xffffff; | 
					
						
							|  |  |  |             val = state; | 
					
						
							|  |  |  |             goto found; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         state = ((state << 8) | v) & 0xffffff; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     val = -1; | 
					
						
							|  |  |  |  found: | 
					
						
							|  |  |  |     *header_state = state; | 
					
						
							|  |  |  |     *size_ptr = n; | 
					
						
							|  |  |  |     return val; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-02-24 19:08:50 +00:00
										 |  |  | #if 0 /* unused, remove? */
 | 
					
						
							| 
									
										
										
										
											2003-11-10 18:47:52 +00:00
										 |  |  | /* XXX: optimize */ | 
					
						
							|  |  |  | static int find_prev_start_code(ByteIOContext *pb, int *size_ptr) | 
					
						
							| 
									
										
										
										
											2001-07-22 14:18:56 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2003-11-10 18:47:52 +00:00
										 |  |  |     int64_t pos, pos_start; | 
					
						
							|  |  |  |     int max_size, start_code; | 
					
						
							| 
									
										
										
										
											2003-10-29 14:20:56 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-11-10 18:47:52 +00:00
										 |  |  |     max_size = *size_ptr; | 
					
						
							|  |  |  |     pos_start = url_ftell(pb); | 
					
						
							| 
									
										
										
										
											2001-07-22 14:18:56 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-11-10 18:47:52 +00:00
										 |  |  |     /* in order to go faster, we fill the buffer */ | 
					
						
							|  |  |  |     pos = pos_start - 16386; | 
					
						
							|  |  |  |     if (pos < 0) | 
					
						
							|  |  |  |         pos = 0; | 
					
						
							|  |  |  |     url_fseek(pb, pos, SEEK_SET); | 
					
						
							|  |  |  |     get_byte(pb); | 
					
						
							| 
									
										
										
										
											2001-07-22 14:18:56 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-11-10 18:47:52 +00:00
										 |  |  |     pos = pos_start; | 
					
						
							|  |  |  |     for(;;) { | 
					
						
							|  |  |  |         pos--; | 
					
						
							|  |  |  |         if (pos < 0 || (pos_start - pos) >= max_size) { | 
					
						
							|  |  |  |             start_code = -1; | 
					
						
							|  |  |  |             goto the_end; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         url_fseek(pb, pos, SEEK_SET); | 
					
						
							|  |  |  |         start_code = get_be32(pb); | 
					
						
							|  |  |  |         if ((start_code & 0xffffff00) == 0x100) | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |  the_end: | 
					
						
							|  |  |  |     *size_ptr = pos_start - pos; | 
					
						
							|  |  |  |     return start_code; | 
					
						
							| 
									
										
										
										
											2001-07-22 14:18:56 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2005-02-24 19:08:50 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2001-07-22 14:18:56 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-04-12 16:50:03 +00:00
										 |  |  | /* read the next PES header. Return its position in ppos 
 | 
					
						
							| 
									
										
										
										
											2003-11-10 18:47:52 +00:00
										 |  |  |    (if not NULL), and its start code, pts and dts. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | static int mpegps_read_pes_header(AVFormatContext *s, | 
					
						
							|  |  |  |                                   int64_t *ppos, int *pstart_code,  | 
					
						
							| 
									
										
										
										
											2004-04-12 16:50:03 +00:00
										 |  |  |                                   int64_t *ppts, int64_t *pdts) | 
					
						
							| 
									
										
										
										
											2001-07-22 14:18:56 +00:00
										 |  |  | { | 
					
						
							|  |  |  |     MpegDemuxContext *m = s->priv_data; | 
					
						
							| 
									
										
										
										
											2003-11-10 18:47:52 +00:00
										 |  |  |     int len, size, startcode, c, flags, header_len; | 
					
						
							|  |  |  |     int64_t pts, dts, last_pos; | 
					
						
							| 
									
										
										
										
											2001-07-22 14:18:56 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-11-10 18:47:52 +00:00
										 |  |  |     last_pos = -1; | 
					
						
							| 
									
										
										
										
											2001-07-22 14:18:56 +00:00
										 |  |  |  redo: | 
					
						
							| 
									
										
										
										
											2003-11-10 18:47:52 +00:00
										 |  |  |         /* next start code (should be immediately after) */ | 
					
						
							|  |  |  |         m->header_state = 0xff; | 
					
						
							|  |  |  |         size = MAX_SYNC_SIZE; | 
					
						
							|  |  |  |         startcode = find_next_start_code(&s->pb, &size, &m->header_state); | 
					
						
							| 
									
										
										
										
											2002-03-17 17:44:45 +00:00
										 |  |  |     //printf("startcode=%x pos=0x%Lx\n", startcode, url_ftell(&s->pb));
 | 
					
						
							| 
									
										
										
										
											2001-07-22 14:18:56 +00:00
										 |  |  |     if (startcode < 0) | 
					
						
							| 
									
										
										
										
											2004-06-19 03:59:34 +00:00
										 |  |  |         return AVERROR_IO; | 
					
						
							| 
									
										
										
										
											2001-07-22 14:18:56 +00:00
										 |  |  |     if (startcode == PACK_START_CODE) | 
					
						
							|  |  |  |         goto redo; | 
					
						
							|  |  |  |     if (startcode == SYSTEM_HEADER_START_CODE) | 
					
						
							|  |  |  |         goto redo; | 
					
						
							|  |  |  |     if (startcode == PADDING_STREAM || | 
					
						
							|  |  |  |         startcode == PRIVATE_STREAM_2) { | 
					
						
							|  |  |  |         /* skip them */ | 
					
						
							|  |  |  |         len = get_be16(&s->pb); | 
					
						
							|  |  |  |         url_fskip(&s->pb, len); | 
					
						
							|  |  |  |         goto redo; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     /* find matching stream */ | 
					
						
							|  |  |  |     if (!((startcode >= 0x1c0 && startcode <= 0x1df) || | 
					
						
							|  |  |  |           (startcode >= 0x1e0 && startcode <= 0x1ef) || | 
					
						
							|  |  |  |           (startcode == 0x1bd))) | 
					
						
							|  |  |  |         goto redo; | 
					
						
							| 
									
										
										
										
											2003-11-10 18:47:52 +00:00
										 |  |  |     if (ppos) { | 
					
						
							|  |  |  |         *ppos = url_ftell(&s->pb) - 4; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2001-07-22 14:18:56 +00:00
										 |  |  |     len = get_be16(&s->pb); | 
					
						
							| 
									
										
										
										
											2002-10-21 15:57:21 +00:00
										 |  |  |     pts = AV_NOPTS_VALUE; | 
					
						
							|  |  |  |     dts = AV_NOPTS_VALUE; | 
					
						
							| 
									
										
										
										
											2001-07-22 14:18:56 +00:00
										 |  |  |     /* stuffing */ | 
					
						
							|  |  |  |     for(;;) { | 
					
						
							| 
									
										
										
										
											2003-11-10 18:47:52 +00:00
										 |  |  |         if (len < 1) | 
					
						
							|  |  |  |             goto redo; | 
					
						
							| 
									
										
										
										
											2001-07-22 14:18:56 +00:00
										 |  |  |         c = get_byte(&s->pb); | 
					
						
							|  |  |  |         len--; | 
					
						
							|  |  |  |         /* XXX: for mpeg1, should test only bit 7 */ | 
					
						
							|  |  |  |         if (c != 0xff)  | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if ((c & 0xc0) == 0x40) { | 
					
						
							|  |  |  |         /* buffer scale & size */ | 
					
						
							| 
									
										
										
										
											2003-11-10 18:47:52 +00:00
										 |  |  |         if (len < 2) | 
					
						
							|  |  |  |             goto redo; | 
					
						
							| 
									
										
										
										
											2001-07-22 14:18:56 +00:00
										 |  |  |         get_byte(&s->pb); | 
					
						
							|  |  |  |         c = get_byte(&s->pb); | 
					
						
							|  |  |  |         len -= 2; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if ((c & 0xf0) == 0x20) { | 
					
						
							| 
									
										
										
										
											2003-11-10 18:47:52 +00:00
										 |  |  |         if (len < 4) | 
					
						
							|  |  |  |             goto redo; | 
					
						
							|  |  |  |         dts = pts = get_pts(&s->pb, c); | 
					
						
							| 
									
										
										
										
											2001-07-22 14:18:56 +00:00
										 |  |  |         len -= 4; | 
					
						
							|  |  |  |     } else if ((c & 0xf0) == 0x30) { | 
					
						
							| 
									
										
										
										
											2003-11-10 18:47:52 +00:00
										 |  |  |         if (len < 9) | 
					
						
							|  |  |  |             goto redo; | 
					
						
							| 
									
										
										
										
											2001-07-22 14:18:56 +00:00
										 |  |  |         pts = get_pts(&s->pb, c); | 
					
						
							|  |  |  |         dts = get_pts(&s->pb, -1); | 
					
						
							|  |  |  |         len -= 9; | 
					
						
							|  |  |  |     } else if ((c & 0xc0) == 0x80) { | 
					
						
							|  |  |  |         /* mpeg 2 PES */ | 
					
						
							|  |  |  |         if ((c & 0x30) != 0) { | 
					
						
							| 
									
										
										
										
											2003-11-10 18:47:52 +00:00
										 |  |  |             /* Encrypted multiplex not handled */ | 
					
						
							|  |  |  |             goto redo; | 
					
						
							| 
									
										
										
										
											2001-07-22 14:18:56 +00:00
										 |  |  |         } | 
					
						
							|  |  |  |         flags = get_byte(&s->pb); | 
					
						
							|  |  |  |         header_len = get_byte(&s->pb); | 
					
						
							|  |  |  |         len -= 2; | 
					
						
							|  |  |  |         if (header_len > len) | 
					
						
							|  |  |  |             goto redo; | 
					
						
							| 
									
										
										
										
											2002-10-04 15:46:59 +00:00
										 |  |  |         if ((flags & 0xc0) == 0x80) { | 
					
						
							| 
									
										
										
										
											2003-11-10 18:47:52 +00:00
										 |  |  |             dts = pts = get_pts(&s->pb, -1); | 
					
						
							|  |  |  |             if (header_len < 5) | 
					
						
							|  |  |  |                 goto redo; | 
					
						
							| 
									
										
										
										
											2001-07-22 14:18:56 +00:00
										 |  |  |             header_len -= 5; | 
					
						
							|  |  |  |             len -= 5; | 
					
						
							|  |  |  |         } if ((flags & 0xc0) == 0xc0) { | 
					
						
							|  |  |  |             pts = get_pts(&s->pb, -1); | 
					
						
							|  |  |  |             dts = get_pts(&s->pb, -1); | 
					
						
							| 
									
										
										
										
											2003-11-10 18:47:52 +00:00
										 |  |  |             if (header_len < 10) | 
					
						
							|  |  |  |                 goto redo; | 
					
						
							| 
									
										
										
										
											2001-07-22 14:18:56 +00:00
										 |  |  |             header_len -= 10; | 
					
						
							|  |  |  |             len -= 10; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         len -= header_len; | 
					
						
							|  |  |  |         while (header_len > 0) { | 
					
						
							|  |  |  |             get_byte(&s->pb); | 
					
						
							|  |  |  |             header_len--; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2004-04-23 21:02:01 +00:00
										 |  |  |     else if( c!= 0xf ) | 
					
						
							|  |  |  |         goto redo; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-07-22 14:18:56 +00:00
										 |  |  |     if (startcode == 0x1bd) { | 
					
						
							| 
									
										
										
										
											2003-11-10 18:47:52 +00:00
										 |  |  |         if (len < 1) | 
					
						
							|  |  |  |             goto redo; | 
					
						
							| 
									
										
										
										
											2001-07-22 14:18:56 +00:00
										 |  |  |         startcode = get_byte(&s->pb); | 
					
						
							|  |  |  |         len--; | 
					
						
							|  |  |  |         if (startcode >= 0x80 && startcode <= 0xbf) { | 
					
						
							|  |  |  |             /* audio: skip header */ | 
					
						
							| 
									
										
										
										
											2003-11-10 18:47:52 +00:00
										 |  |  |             if (len < 3) | 
					
						
							|  |  |  |                 goto redo; | 
					
						
							| 
									
										
										
										
											2001-07-22 14:18:56 +00:00
										 |  |  |             get_byte(&s->pb); | 
					
						
							|  |  |  |             get_byte(&s->pb); | 
					
						
							|  |  |  |             get_byte(&s->pb); | 
					
						
							|  |  |  |             len -= 3; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2004-01-13 22:02:49 +00:00
										 |  |  |     if(dts != AV_NOPTS_VALUE && ppos){ | 
					
						
							|  |  |  |         int i; | 
					
						
							|  |  |  |         for(i=0; i<s->nb_streams; i++){ | 
					
						
							|  |  |  |             if(startcode == s->streams[i]->id) { | 
					
						
							| 
									
										
										
										
											2005-03-13 00:13:01 +00:00
										 |  |  |                 av_add_index_entry(s->streams[i], *ppos, dts, 0, AVINDEX_KEYFRAME /* FIXME keyframe? */); | 
					
						
							| 
									
										
										
										
											2004-01-13 22:02:49 +00:00
										 |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |      | 
					
						
							| 
									
										
										
										
											2003-11-10 18:47:52 +00:00
										 |  |  |     *pstart_code = startcode; | 
					
						
							|  |  |  |     *ppts = pts; | 
					
						
							|  |  |  |     *pdts = dts; | 
					
						
							|  |  |  |     return len; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int mpegps_read_packet(AVFormatContext *s, | 
					
						
							|  |  |  |                               AVPacket *pkt) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     AVStream *st; | 
					
						
							| 
									
										
										
										
											2004-06-19 03:59:34 +00:00
										 |  |  |     int len, startcode, i, type, codec_id = 0; | 
					
						
							| 
									
										
										
										
											2004-01-13 22:02:49 +00:00
										 |  |  |     int64_t pts, dts, dummy_pos; //dummy_pos is needed for the index building to work
 | 
					
						
							| 
									
										
										
										
											2003-11-10 18:47:52 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |  redo: | 
					
						
							| 
									
										
										
										
											2004-04-12 16:50:03 +00:00
										 |  |  |     len = mpegps_read_pes_header(s, &dummy_pos, &startcode, &pts, &dts); | 
					
						
							| 
									
										
										
										
											2003-11-10 18:47:52 +00:00
										 |  |  |     if (len < 0) | 
					
						
							|  |  |  |         return len; | 
					
						
							| 
									
										
										
										
											2003-12-09 18:06:18 +00:00
										 |  |  |      | 
					
						
							| 
									
										
										
										
											2001-07-22 14:18:56 +00:00
										 |  |  |     /* now find stream */ | 
					
						
							|  |  |  |     for(i=0;i<s->nb_streams;i++) { | 
					
						
							|  |  |  |         st = s->streams[i]; | 
					
						
							|  |  |  |         if (st->id == startcode) | 
					
						
							|  |  |  |             goto found; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2002-05-20 16:29:40 +00:00
										 |  |  |     if (startcode >= 0x1e0 && startcode <= 0x1ef) { | 
					
						
							|  |  |  |         type = CODEC_TYPE_VIDEO; | 
					
						
							| 
									
										
										
										
											2003-12-16 11:25:30 +00:00
										 |  |  |         codec_id = CODEC_ID_MPEG2VIDEO; | 
					
						
							| 
									
										
										
										
											2002-05-20 16:29:40 +00:00
										 |  |  |     } else if (startcode >= 0x1c0 && startcode <= 0x1df) { | 
					
						
							|  |  |  |         type = CODEC_TYPE_AUDIO; | 
					
						
							|  |  |  |         codec_id = CODEC_ID_MP2; | 
					
						
							| 
									
										
										
										
											2004-07-14 01:32:14 +00:00
										 |  |  |     } else if (startcode >= 0x80 && startcode <= 0x89) { | 
					
						
							| 
									
										
										
										
											2002-05-20 16:29:40 +00:00
										 |  |  |         type = CODEC_TYPE_AUDIO; | 
					
						
							|  |  |  |         codec_id = CODEC_ID_AC3; | 
					
						
							| 
									
										
										
										
											2004-07-14 01:32:14 +00:00
										 |  |  |     } else if (startcode >= 0x8a && startcode <= 0x9f) { | 
					
						
							|  |  |  |         type = CODEC_TYPE_AUDIO; | 
					
						
							|  |  |  |         codec_id = CODEC_ID_DTS; | 
					
						
							| 
									
										
										
										
											2003-01-31 17:04:46 +00:00
										 |  |  |     } else if (startcode >= 0xa0 && startcode <= 0xbf) { | 
					
						
							|  |  |  |         type = CODEC_TYPE_AUDIO; | 
					
						
							|  |  |  |         codec_id = CODEC_ID_PCM_S16BE; | 
					
						
							| 
									
										
										
										
											2002-05-20 16:29:40 +00:00
										 |  |  |     } else { | 
					
						
							|  |  |  |     skip: | 
					
						
							|  |  |  |         /* skip packet */ | 
					
						
							|  |  |  |         url_fskip(&s->pb, len); | 
					
						
							|  |  |  |         goto redo; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2002-10-04 15:46:59 +00:00
										 |  |  |     /* no stream found: add a new stream */ | 
					
						
							|  |  |  |     st = av_new_stream(s, startcode); | 
					
						
							|  |  |  |     if (!st)  | 
					
						
							|  |  |  |         goto skip; | 
					
						
							| 
									
										
										
										
											2002-05-20 16:29:40 +00:00
										 |  |  |     st->codec.codec_type = type; | 
					
						
							|  |  |  |     st->codec.codec_id = codec_id; | 
					
						
							| 
									
										
										
										
											2003-11-10 18:47:52 +00:00
										 |  |  |     if (codec_id != CODEC_ID_PCM_S16BE) | 
					
						
							|  |  |  |         st->need_parsing = 1; | 
					
						
							| 
									
										
										
										
											2001-07-22 14:18:56 +00:00
										 |  |  |  found: | 
					
						
							| 
									
										
										
										
											2005-01-22 13:36:02 +00:00
										 |  |  |     if(st->discard) | 
					
						
							|  |  |  |         goto skip; | 
					
						
							| 
									
										
										
										
											2003-01-31 17:04:46 +00:00
										 |  |  |     if (startcode >= 0xa0 && startcode <= 0xbf) { | 
					
						
							|  |  |  |         int b1, freq; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         /* for LPCM, we just skip the header and consider it is raw
 | 
					
						
							|  |  |  |            audio data */ | 
					
						
							|  |  |  |         if (len <= 3) | 
					
						
							|  |  |  |             goto skip; | 
					
						
							|  |  |  |         get_byte(&s->pb); /* emphasis (1), muse(1), reserved(1), frame number(5) */ | 
					
						
							|  |  |  |         b1 = get_byte(&s->pb); /* quant (2), freq(2), reserved(1), channels(3) */ | 
					
						
							|  |  |  |         get_byte(&s->pb); /* dynamic range control (0x80 = off) */ | 
					
						
							|  |  |  |         len -= 3; | 
					
						
							|  |  |  |         freq = (b1 >> 4) & 3; | 
					
						
							|  |  |  |         st->codec.sample_rate = lpcm_freq_tab[freq]; | 
					
						
							|  |  |  |         st->codec.channels = 1 + (b1 & 7); | 
					
						
							|  |  |  |         st->codec.bit_rate = st->codec.channels * st->codec.sample_rate * 2; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2001-07-22 14:18:56 +00:00
										 |  |  |     av_new_packet(pkt, len); | 
					
						
							|  |  |  |     get_buffer(&s->pb, pkt->data, pkt->size); | 
					
						
							|  |  |  |     pkt->pts = pts; | 
					
						
							| 
									
										
										
										
											2003-11-10 18:47:52 +00:00
										 |  |  |     pkt->dts = dts; | 
					
						
							| 
									
										
										
										
											2002-05-20 16:29:40 +00:00
										 |  |  |     pkt->stream_index = st->index; | 
					
						
							| 
									
										
										
										
											2003-12-09 18:06:18 +00:00
										 |  |  | #if 0
 | 
					
						
							| 
									
										
										
										
											2005-01-22 13:36:02 +00:00
										 |  |  |     av_log(s, AV_LOG_DEBUG, "%d: pts=%0.3f dts=%0.3f size=%d\n", | 
					
						
							|  |  |  |            pkt->stream_index, pkt->pts / 90000.0, pkt->dts / 90000.0, pkt->size); | 
					
						
							| 
									
										
										
										
											2003-12-09 18:06:18 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2004-06-19 03:59:34 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-07-22 14:18:56 +00:00
										 |  |  |     return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2002-05-20 16:29:40 +00:00
										 |  |  | static int mpegps_read_close(AVFormatContext *s) | 
					
						
							| 
									
										
										
										
											2001-07-22 14:18:56 +00:00
										 |  |  | { | 
					
						
							|  |  |  |     return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-11-10 18:47:52 +00:00
										 |  |  | static int64_t mpegps_read_dts(AVFormatContext *s, int stream_index,  | 
					
						
							| 
									
										
										
										
											2004-04-12 16:50:03 +00:00
										 |  |  |                                int64_t *ppos, int64_t pos_limit) | 
					
						
							| 
									
										
										
										
											2003-11-10 18:47:52 +00:00
										 |  |  | { | 
					
						
							|  |  |  |     int len, startcode; | 
					
						
							|  |  |  |     int64_t pos, pts, dts; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     pos = *ppos; | 
					
						
							|  |  |  | #ifdef DEBUG_SEEK
 | 
					
						
							|  |  |  |     printf("read_dts: pos=0x%llx next=%d -> ", pos, find_next); | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  |     url_fseek(&s->pb, pos, SEEK_SET); | 
					
						
							|  |  |  |     for(;;) { | 
					
						
							| 
									
										
										
										
											2004-04-12 16:50:03 +00:00
										 |  |  |         len = mpegps_read_pes_header(s, &pos, &startcode, &pts, &dts); | 
					
						
							| 
									
										
										
										
											2003-11-10 18:47:52 +00:00
										 |  |  |         if (len < 0) { | 
					
						
							|  |  |  | #ifdef DEBUG_SEEK
 | 
					
						
							|  |  |  |             printf("none (ret=%d)\n", len); | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  |             return AV_NOPTS_VALUE; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         if (startcode == s->streams[stream_index]->id &&  | 
					
						
							|  |  |  |             dts != AV_NOPTS_VALUE) { | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2004-04-12 16:50:03 +00:00
										 |  |  |         url_fskip(&s->pb, len); | 
					
						
							| 
									
										
										
										
											2003-11-10 18:47:52 +00:00
										 |  |  |     } | 
					
						
							|  |  |  | #ifdef DEBUG_SEEK
 | 
					
						
							|  |  |  |     printf("pos=0x%llx dts=0x%llx %0.3f\n", pos, dts, dts / 90000.0); | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  |     *ppos = pos; | 
					
						
							| 
									
										
										
										
											2004-05-23 16:26:12 +00:00
										 |  |  |     return dts; | 
					
						
							| 
									
										
										
										
											2003-11-10 18:47:52 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-10-14 04:15:53 +00:00
										 |  |  | #ifdef CONFIG_ENCODERS
 | 
					
						
							| 
									
										
										
										
											2002-10-15 10:22:23 +00:00
										 |  |  | static AVOutputFormat mpeg1system_mux = { | 
					
						
							| 
									
										
										
										
											2001-07-22 14:18:56 +00:00
										 |  |  |     "mpeg", | 
					
						
							| 
									
										
										
										
											2002-10-15 10:22:23 +00:00
										 |  |  |     "MPEG1 System format", | 
					
						
							| 
									
										
										
										
											2002-12-20 23:10:58 +00:00
										 |  |  |     "video/mpeg", | 
					
						
							| 
									
										
										
										
											2002-10-15 10:22:23 +00:00
										 |  |  |     "mpg,mpeg", | 
					
						
							|  |  |  |     sizeof(MpegMuxContext), | 
					
						
							|  |  |  |     CODEC_ID_MP2, | 
					
						
							|  |  |  |     CODEC_ID_MPEG1VIDEO, | 
					
						
							|  |  |  |     mpeg_mux_init, | 
					
						
							|  |  |  |     mpeg_mux_write_packet, | 
					
						
							|  |  |  |     mpeg_mux_end, | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static AVOutputFormat mpeg1vcd_mux = { | 
					
						
							|  |  |  |     "vcd", | 
					
						
							|  |  |  |     "MPEG1 System format (VCD)", | 
					
						
							| 
									
										
										
										
											2002-12-20 23:10:58 +00:00
										 |  |  |     "video/mpeg", | 
					
						
							| 
									
										
										
										
											2002-10-15 10:22:23 +00:00
										 |  |  |     NULL, | 
					
						
							|  |  |  |     sizeof(MpegMuxContext), | 
					
						
							|  |  |  |     CODEC_ID_MP2, | 
					
						
							|  |  |  |     CODEC_ID_MPEG1VIDEO, | 
					
						
							|  |  |  |     mpeg_mux_init, | 
					
						
							|  |  |  |     mpeg_mux_write_packet, | 
					
						
							|  |  |  |     mpeg_mux_end, | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static AVOutputFormat mpeg2vob_mux = { | 
					
						
							|  |  |  |     "vob", | 
					
						
							|  |  |  |     "MPEG2 PS format (VOB)", | 
					
						
							| 
									
										
										
										
											2002-12-20 23:10:58 +00:00
										 |  |  |     "video/mpeg", | 
					
						
							| 
									
										
										
										
											2002-10-15 10:22:23 +00:00
										 |  |  |     "vob", | 
					
						
							| 
									
										
										
										
											2002-05-20 16:29:40 +00:00
										 |  |  |     sizeof(MpegMuxContext), | 
					
						
							| 
									
										
										
										
											2001-07-22 14:18:56 +00:00
										 |  |  |     CODEC_ID_MP2, | 
					
						
							| 
									
										
										
										
											2003-12-16 11:25:30 +00:00
										 |  |  |     CODEC_ID_MPEG2VIDEO, | 
					
						
							| 
									
										
										
										
											2001-07-22 14:18:56 +00:00
										 |  |  |     mpeg_mux_init, | 
					
						
							|  |  |  |     mpeg_mux_write_packet, | 
					
						
							|  |  |  |     mpeg_mux_end, | 
					
						
							| 
									
										
										
										
											2002-05-20 16:29:40 +00:00
										 |  |  | }; | 
					
						
							| 
									
										
										
										
											2004-02-19 22:34:13 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | /* Same as mpeg2vob_mux except that the pack size is 2324 */ | 
					
						
							|  |  |  | static AVOutputFormat mpeg2svcd_mux = { | 
					
						
							|  |  |  |     "svcd", | 
					
						
							|  |  |  |     "MPEG2 PS format (VOB)", | 
					
						
							|  |  |  |     "video/mpeg", | 
					
						
							|  |  |  |     "vob", | 
					
						
							|  |  |  |     sizeof(MpegMuxContext), | 
					
						
							|  |  |  |     CODEC_ID_MP2, | 
					
						
							|  |  |  |     CODEC_ID_MPEG2VIDEO, | 
					
						
							|  |  |  |     mpeg_mux_init, | 
					
						
							|  |  |  |     mpeg_mux_write_packet, | 
					
						
							|  |  |  |     mpeg_mux_end, | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-10-03 18:21:45 +00:00
										 |  |  | /*  Same as mpeg2vob_mux except the 'is_dvd' flag is set to produce NAV pkts */ | 
					
						
							|  |  |  | static AVOutputFormat mpeg2dvd_mux = { | 
					
						
							|  |  |  |     "dvd", | 
					
						
							|  |  |  |     "MPEG2 PS format (DVD VOB)", | 
					
						
							|  |  |  |     "video/mpeg", | 
					
						
							|  |  |  |     "dvd", | 
					
						
							|  |  |  |     sizeof(MpegMuxContext), | 
					
						
							|  |  |  |     CODEC_ID_MP2, | 
					
						
							|  |  |  |     CODEC_ID_MPEG2VIDEO, | 
					
						
							|  |  |  |     mpeg_mux_init, | 
					
						
							|  |  |  |     mpeg_mux_write_packet, | 
					
						
							|  |  |  |     mpeg_mux_end, | 
					
						
							|  |  |  | }; | 
					
						
							| 
									
										
										
										
											2004-02-19 22:34:13 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-10-14 04:15:53 +00:00
										 |  |  | #endif //CONFIG_ENCODERS
 | 
					
						
							| 
									
										
										
										
											2001-07-22 14:18:56 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-08-08 17:54:05 +00:00
										 |  |  | AVInputFormat mpegps_demux = { | 
					
						
							| 
									
										
										
										
											2002-05-20 16:29:40 +00:00
										 |  |  |     "mpeg", | 
					
						
							|  |  |  |     "MPEG PS format", | 
					
						
							|  |  |  |     sizeof(MpegDemuxContext), | 
					
						
							|  |  |  |     mpegps_probe, | 
					
						
							|  |  |  |     mpegps_read_header, | 
					
						
							|  |  |  |     mpegps_read_packet, | 
					
						
							|  |  |  |     mpegps_read_close, | 
					
						
							| 
									
										
										
										
											2004-04-12 16:50:03 +00:00
										 |  |  |     NULL, //mpegps_read_seek,
 | 
					
						
							|  |  |  |     mpegps_read_dts, | 
					
						
							| 
									
										
										
										
											2001-07-22 14:18:56 +00:00
										 |  |  | }; | 
					
						
							| 
									
										
										
										
											2002-05-20 16:29:40 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | int mpegps_init(void) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2003-10-14 04:15:53 +00:00
										 |  |  | #ifdef CONFIG_ENCODERS
 | 
					
						
							| 
									
										
										
										
											2002-10-15 10:22:23 +00:00
										 |  |  |     av_register_output_format(&mpeg1system_mux); | 
					
						
							|  |  |  |     av_register_output_format(&mpeg1vcd_mux); | 
					
						
							|  |  |  |     av_register_output_format(&mpeg2vob_mux); | 
					
						
							| 
									
										
										
										
											2004-02-19 22:34:13 +00:00
										 |  |  |     av_register_output_format(&mpeg2svcd_mux); | 
					
						
							| 
									
										
										
										
											2004-10-03 18:21:45 +00:00
										 |  |  |     av_register_output_format(&mpeg2dvd_mux); | 
					
						
							| 
									
										
										
										
											2003-10-14 04:15:53 +00:00
										 |  |  | #endif //CONFIG_ENCODERS
 | 
					
						
							| 
									
										
										
										
											2002-05-20 16:29:40 +00:00
										 |  |  |     av_register_input_format(&mpegps_demux); | 
					
						
							|  |  |  |     return 0; | 
					
						
							|  |  |  | } |