annotate libmpdemux/muxer_mpeg.c @ 10394:59982e3c403b

Fix -shuffle with remote playlist
author albeu
date Tue, 08 Jul 2003 10:45:05 +0000
parents 12fc55eb3373
children b677b25a898d
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
8585
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
1
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
2 #include <stdio.h>
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
3 #include <stdlib.h>
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
4 #include <string.h>
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
5 #include <sys/types.h>
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
6
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
7 #include "config.h"
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
8 #include "../version.h"
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
9
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
10 #include "wine/mmreg.h"
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
11 #include "wine/avifmt.h"
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
12 #include "wine/vfw.h"
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
13 #include "bswap.h"
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
14
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
15 #include "muxer.h"
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
16
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
17 // 18 bytes reserved for block headers and STD
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
18 #define MUXER_MPEG_DATASIZE (MUXER_MPEG_BLOCKSIZE-18)
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
19
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
20 // ISO-11172 requirements
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
21 #define MPEG_MAX_PTS_DELAY 90000 /* 1s */
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
22 #define MPEG_MAX_SCR_INTERVAL 63000 /* 0.7s */
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
23
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
24 // suggestions
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
25 #define MPEG_STARTPTS 45000 /* 0.5s */
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
26 #define MPEG_MIN_PTS_DELAY 9000 /* 0.1s */
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
27 #define MPEG_STARTSCR 9 /* 0.1ms */
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
28
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
29 //static unsigned int mpeg_min_delay;
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
30 //static unsigned int mpeg_max_delay;
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
31
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
32 static muxer_stream_t* mpegfile_new_stream(muxer_t *muxer,int type){
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
33 muxer_stream_t *s;
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
34
9007
12fc55eb3373 Cleanup of the muxer API, func parameters muxer & muxer_f eliminated.
arpi
parents: 8585
diff changeset
35 if (!muxer) return NULL;
8585
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
36 if(muxer->avih.dwStreams>=MUXER_MAX_STREAMS){
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
37 printf("Too many streams! increase MUXER_MAX_STREAMS !\n");
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
38 return NULL;
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
39 }
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
40 switch (type) {
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
41 case MUXER_TYPE_VIDEO:
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
42 if (muxer->num_videos >= 15) {
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
43 printf ("MPEG stream can't contain above of 15 video streams!\n");
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
44 return NULL;
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
45 }
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
46 break;
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
47 case MUXER_TYPE_AUDIO:
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
48 if (muxer->avih.dwStreams - muxer->num_videos >= 31) {
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
49 printf ("MPEG stream can't contain above of 31 audio streams!\n");
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
50 return NULL;
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
51 }
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
52 break;
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
53 default:
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
54 printf ("Unknown stream type!\n");
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
55 return NULL;
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
56 }
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
57 s=malloc(sizeof(muxer_stream_t));
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
58 memset(s,0,sizeof(muxer_stream_t));
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
59 if(!s) return NULL; // no mem!?
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
60 if (!(s->b_buffer = malloc (MUXER_MPEG_BLOCKSIZE))) {
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
61 free (s);
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
62 return NULL; // no mem?!
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
63 } else if (type == MUXER_TYPE_VIDEO) {
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
64 s->ckid = be2me_32 (0x1e0 + muxer->num_videos);
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
65 muxer->num_videos++;
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
66 s->h.fccType=streamtypeVIDEO;
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
67 if(!muxer->def_v) muxer->def_v=s;
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
68 // printf ("Added video stream %d\n", muxer->num_videos);
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
69 } else { // MUXER_TYPE_AUDIO
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
70 s->ckid = be2me_32 (0x1c0 + s->id - muxer->num_videos);
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
71 s->h.fccType=streamtypeAUDIO;
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
72 // printf ("Added audio stream %d\n", s->id - muxer->num_videos + 1);
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
73 }
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
74 muxer->streams[muxer->avih.dwStreams]=s;
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
75 s->type=type;
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
76 s->id=muxer->avih.dwStreams;
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
77 s->timer=0.0;
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
78 s->size=0;
9007
12fc55eb3373 Cleanup of the muxer API, func parameters muxer & muxer_f eliminated.
arpi
parents: 8585
diff changeset
79 s->muxer=muxer;
8585
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
80 muxer->avih.dwStreams++;
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
81 return s;
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
82 }
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
83
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
84 static void write_mpeg_ts(unsigned char *b, unsigned int ts, char mod) {
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
85 b[0] = ((ts >> 29) & 0xf) | 1 | mod;
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
86 b[1] = (ts >> 22) & 0xff;
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
87 b[2] = ((ts >> 14) & 0xff) | 1;
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
88 b[3] = (ts >> 7) & 0xff;
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
89 b[4] = ((ts << 1) & 0xff) | 1;
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
90 }
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
91
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
92 static void write_mpeg_rate(unsigned char *b, unsigned int rate) {
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
93 if (rate)
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
94 rate--; // for round upward
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
95 rate /= 50;
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
96 rate++; // round upward
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
97 b[0] = ((rate >> 15) & 0x7f) | 0x80;
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
98 b[1] = (rate >> 7) & 0xff;
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
99 b[2] = ((rate << 1) & 0xff) | 1;
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
100 }
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
101
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
102 static void write_mpeg_std(unsigned char *b, unsigned int size, char mod) {
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
103 if (size)
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
104 size--; // for round upward
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
105 if (size < (128 << 8))
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
106 size >>= 7; // by 128 bytes
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
107 else {
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
108 size >>= 10;
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
109 size |= 0x2000; // by 1kbyte
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
110 }
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
111 size++; // round upward
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
112 b[0] = ((size >> 8) & 0x3f) | 0x40 | mod;
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
113 b[1] = size & 0xff;
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
114 }
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
115
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
116 static int write_mpeg_block(muxer_t *muxer, muxer_stream_t *s, FILE *f, char *bl, size_t len, int isoend){
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
117 size_t sz; // rest in block buffer
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
118 unsigned char buff[12]; // 0x1ba header
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
119 unsigned int mints=0;
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
120 uint16_t l1;
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
121
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
122 if (s->b_buffer_ptr == 0) { // 00001111 if no PTS
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
123 s->b_buffer[0] = 0xf;
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
124 s->b_buffer_ptr = 1;
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
125 sz = MUXER_MPEG_DATASIZE-1;
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
126 } else if (s->b_buffer_ptr > MUXER_MPEG_DATASIZE) {
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
127 printf ("Unknown error in write_mpeg_block()!\n");
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
128 return 0;
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
129 } else {
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
130 sz = MUXER_MPEG_DATASIZE - s->b_buffer_ptr;
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
131 if (s->b_buffer[7] == 0xff) // PTS not set yet
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
132 s->b_buffer[11] = 0xf; // terminate stuFFing bytes
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
133 }
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
134 if (len > sz)
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
135 len = sz;
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
136 *(uint32_t *)buff = be2me_32 (0x1ba);
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
137 write_mpeg_ts (buff+4, muxer->file_end, 0x20); // 0010 and SCR
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
138 write_mpeg_rate (buff+9, muxer->sysrate);
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
139 fwrite (buff, 12, 1, f);
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
140 fwrite (&s->ckid, 4, 1, f); // stream_id
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
141 memset (buff, 0xff, 12); // stuFFing bytes
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
142 sz -= len;
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
143 // calculate padding bytes in buffer
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
144 while (mints < s->b_buffer_ptr && s->b_buffer[mints] == 0xff) mints++;
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
145 if (mints+sz < 12) { // cannot write padding block so write up to 12 stuFFing bytes
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
146 l1 = be2me_16 (MUXER_MPEG_DATASIZE);
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
147 fwrite (&l1, 2, 1, f);
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
148 mints = 0; // so stuFFed bytes will be written all
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
149 if (sz)
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
150 fwrite (buff, sz, 1, f);
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
151 sz = 0; // no padding block anyway
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
152 } else { // use padding block
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
153 if (sz > 6) // sufficient for PAD header so don't shorter data
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
154 mints = 0;
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
155 else
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
156 sz += mints; // skip stuFFing bytes (sz>8 here)
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
157 l1 = be2me_16 (s->b_buffer_ptr+len-mints);
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
158 fwrite (&l1, 2, 1, f);
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
159 }
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
160 if (s->b_buffer_ptr)
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
161 fwrite (s->b_buffer+mints, s->b_buffer_ptr-mints, 1, f);
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
162 if (len)
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
163 fwrite (bl, len, 1, f);
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
164 if (sz > 6) { // padding block (0x1be)
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
165 uint32_t l0;
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
166
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
167 if (isoend)
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
168 l0 = be2me_32 (0x1b9);
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
169 else
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
170 l0 = be2me_32 (0x1be);
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
171 sz -= 6;
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
172 l1 = be2me_16 (sz);
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
173 fwrite (&l0, 4, 1, f);
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
174 fwrite (&l1, 2, 1, f);
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
175 memset (s->b_buffer, 0xff, sz); // stuFFing bytes
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
176 fwrite (s->b_buffer, sz, 1, f);
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
177 }
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
178 s->b_buffer_ptr = 0;
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
179 muxer->movi_end += MUXER_MPEG_BLOCKSIZE;
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
180 // prepare timestamps for next pack
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
181 mints = (MUXER_MPEG_BLOCKSIZE*90000/muxer->sysrate)+1; // min ts delta
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
182 sz = (int)(s->timer*90000) + MPEG_STARTPTS; // new PTS
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
183 if (sz > muxer->file_end)
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
184 sz -= muxer->file_end; // suggested ts delta
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
185 else
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
186 {
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
187 sz = 0;
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
188 printf ("Error in stream: PTS earlier than SCR!\n");
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
189 }
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
190 if (sz > MPEG_MAX_PTS_DELAY) {
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
191 // printf ("Warning: attempt to set PTS to SCR delay to %u \n", sz);
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
192 mints = sz-MPEG_MAX_PTS_DELAY; // try to compensate
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
193 if (mints > MPEG_MAX_SCR_INTERVAL) {
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
194 printf ("Error in stream: SCR interval %u is too big!\n", mints);
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
195 }
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
196 } else if (sz > 54000) // assume 0.3...0.7s is optimal
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
197 mints += (sz-45000)>>2; // reach 0.5s in 4 blocks ?
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
198 else if (sz < 27000) {
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
199 unsigned int newsysrate = 0;
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
200
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
201 if (s->timer > 0.5) // too early to calculate???
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
202 newsysrate = muxer->movi_end/(s->timer*0.4); // pike-factor 2.5 (8dB)
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
203 if (sz < MPEG_MIN_PTS_DELAY)
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
204 printf ("Error in stream: PTS to SCR delay %u is too little!\n", sz);
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
205 if (muxer->sysrate < newsysrate)
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
206 muxer->sysrate = newsysrate; // increase next rate to current rate
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
207 else if (!newsysrate)
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
208 muxer->sysrate += muxer->sysrate>>3; // increase next rate by 25%
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
209 }
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
210 muxer->file_end += mints; // update the system timestamp
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
211 return len;
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
212 }
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
213
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
214 static void set_mpeg_pts(muxer_t *muxer, muxer_stream_t *s, unsigned int pts) {
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
215 unsigned int dts, nts;
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
216
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
217 if (s->b_buffer_ptr != 0 && s->b_buffer[7] != 0xff)
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
218 return; // already set
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
219 if (s->b_buffer_ptr == 0) {
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
220 memset (s->b_buffer, 0xff, 7); // reserved for PTS or STD, stuFFing for now
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
221 s->b_buffer_ptr = 12;
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
222 }
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
223 dts = (int)(s->timer*90000) + MPEG_STARTPTS; // PTS
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
224 if (pts) {
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
225 write_mpeg_ts (s->b_buffer+2, pts, 0x30); // 0011 and both PTS/DTS
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
226 } else {
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
227 write_mpeg_ts (s->b_buffer+7, dts, 0x20); // 0010 and PTS only
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
228 return;
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
229 }
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
230 nts = dts - muxer->file_end;
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
231 // if (nts < mpeg_min_delay) mpeg_min_delay = nts;
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
232 // if (nts > mpeg_max_delay) mpeg_max_delay = nts;
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
233 nts = 180000*s->h.dwScale/s->h.dwRate; // two frames
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
234 if (dts-nts < muxer->file_end) {
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
235 dts += muxer->file_end;
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
236 dts /= 2; // calculate average time
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
237 printf ("Warning: DTS to SCR delay is too small\n");
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
238 }
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
239 else
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
240 dts -= nts/2; // one frame :)
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
241 write_mpeg_ts (s->b_buffer+7, dts, 0x10);
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
242 }
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
243
9007
12fc55eb3373 Cleanup of the muxer API, func parameters muxer & muxer_f eliminated.
arpi
parents: 8585
diff changeset
244 static void mpegfile_write_chunk(muxer_stream_t *s,size_t len,unsigned int flags){
8585
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
245 size_t ptr=0, sz;
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
246 unsigned int pts=0;
9007
12fc55eb3373 Cleanup of the muxer API, func parameters muxer & muxer_f eliminated.
arpi
parents: 8585
diff changeset
247 muxer_t *muxer = s->muxer;
12fc55eb3373 Cleanup of the muxer API, func parameters muxer & muxer_f eliminated.
arpi
parents: 8585
diff changeset
248 FILE *f;
8585
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
249
9007
12fc55eb3373 Cleanup of the muxer API, func parameters muxer & muxer_f eliminated.
arpi
parents: 8585
diff changeset
250 f = muxer->file;
8585
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
251 if (s->type == MUXER_TYPE_VIDEO) { // try to recognize frame type...
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
252 if (s->buffer[0] != 0 || s->buffer[1] != 0 || s->buffer[2] != 1 || len<6) {
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
253 printf ("Unknown block type, possibly non-MPEG stream!\n");
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
254 sz = len;
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
255 // return;
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
256 } else if (s->buffer[3] == 0 || s->buffer[3] == 0xb3 ||
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
257 s->buffer[3] == 0xb8) { // Picture or GOP
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
258 int temp_ref;
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
259 int pt;
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
260
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
261 if (s->buffer[3]) { // GOP -- scan for Picture
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
262 s->gop_start = s->h.dwLength;
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
263 while (ptr < len-5 && (s->buffer[ptr] != 0 || s->buffer[ptr+1] != 0 ||
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
264 s->buffer[ptr+2] != 1 || s->buffer[ptr+3] != 0)) ptr++;
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
265 if (s->b_buffer_ptr > MUXER_MPEG_DATASIZE-39-12) { // 39 bytes for Gop+Pic+Slice headers
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
266 write_mpeg_block (muxer, s, f, NULL, 0, 0);
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
267 }
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
268 }
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
269 if (ptr >= len-5) {
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
270 pt = 0; // Picture not found?!
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
271 temp_ref = 0;
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
272 printf ("Warning: picture not found in GOP!\n");
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
273 } else {
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
274 pt = (s->buffer[ptr+5]>>3) & 7;
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
275 temp_ref = (s->buffer[ptr+4]<<2)+(s->buffer[ptr+5]>>6);
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
276 }
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
277 ptr = 0;
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
278 temp_ref += s->gop_start;
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
279 switch (pt) {
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
280 case 2: // predictive
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
281 if (s->ipb[0]) {
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
282 sz = len + s->ipb[0];
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
283 if (s->ipb[0] < s->ipb[2])
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
284 s->ipb[0] = s->ipb[2];
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
285 s->ipb[2] = 0;
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
286 } else if (s->ipb[2]) {
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
287 sz = len + s->ipb[2];
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
288 s->ipb[0] = s->ipb[2];
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
289 s->ipb[2] = 0;
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
290 } else
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
291 sz = 4 * len; // no bidirectional frames yet?
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
292 s->ipb[1] = len;
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
293 // pictires may be not in frame sequence so recalculate timer
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
294 pts = (int)(90000*((double)temp_ref*s->h.dwScale/s->h.dwRate)) + MPEG_STARTPTS;
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
295 break;
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
296 case 3: // bidirectional
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
297 s->ipb[2] += len;
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
298 sz = s->ipb[1] + s->ipb[2];
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
299 // pictires may be not in frame sequence so recalculate timer
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
300 s->timer = (double)temp_ref*s->h.dwScale/s->h.dwRate;
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
301 break;
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
302 default: // intra-coded
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
303 // pictires may be not in frame sequence so recalculate timer
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
304 pts = (int)(90000*((double)temp_ref*s->h.dwScale/s->h.dwRate)) + MPEG_STARTPTS;
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
305 sz = len; // no extra buffer for it...
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
306 }
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
307 } else {
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
308 printf ("Unknown block type, possibly non-MPEG stream!\n");
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
309 sz = len;
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
310 // return;
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
311 }
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
312 sz <<= 1;
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
313 } else { // MUXER_TYPE_AUDIO
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
314 if (len < 2*MUXER_MPEG_DATASIZE)
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
315 sz = 2*MUXER_MPEG_DATASIZE; // min requirement
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
316 else
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
317 sz = len;
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
318 }
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
319 set_mpeg_pts (muxer, s, pts);
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
320 // alter counters:
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
321 if (s->h.dwSampleSize) {
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
322 // CBR
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
323 s->h.dwLength += len/s->h.dwSampleSize;
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
324 if (len%s->h.dwSampleSize) printf("Warning! len isn't divisable by samplesize!\n");
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
325 } else {
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
326 // VBR
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
327 s->h.dwLength++;
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
328 }
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
329 if (!muxer->sysrate) {
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
330 muxer->sysrate = 2108000/8; // constrained stream parameter
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
331 muxer->file_end = MUXER_MPEG_BLOCKSIZE*90000/muxer->sysrate + MPEG_STARTSCR+1;
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
332 }
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
333 if (sz > s->h.dwSuggestedBufferSize) { // increase and set STD
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
334 s->h.dwSuggestedBufferSize = sz;
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
335 if (s->b_buffer[2] != 0xff) // has both PTS and DTS
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
336 write_mpeg_std (s->b_buffer, s->h.dwSuggestedBufferSize, 0x40); // 01
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
337 else // has only PTS
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
338 write_mpeg_std (s->b_buffer+5, s->h.dwSuggestedBufferSize, 0x40); // 01
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
339 }
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
340 s->size += len;
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
341 // write out block(s) if it's ready
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
342 while (s->b_buffer_ptr+len >= MUXER_MPEG_DATASIZE-12) { // reserved for std and pts
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
343 // write out the block
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
344 sz = write_mpeg_block (muxer, s, f, &s->buffer[ptr], len, 0);
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
345 // recalculate the rest of chunk
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
346 ptr += sz;
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
347 len -= sz;
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
348 }
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
349 s->timer = (double)s->h.dwLength*s->h.dwScale/s->h.dwRate;
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
350 if (len) { // save rest in buffer
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
351 if (s->b_buffer_ptr == 0) {
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
352 memset (s->b_buffer, 0xff, 12); // stuFFing bytes for now
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
353 if (s->type == MUXER_TYPE_AUDIO && s->h.dwSampleSize) { // CBR audio
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
354 sz = s->h.dwLength - len/s->h.dwSampleSize; // first sample number
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
355 write_mpeg_ts (s->b_buffer+7,
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
356 (int)(90000*((double)sz*s->h.dwScale/s->h.dwRate)) + MPEG_STARTPTS,
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
357 0x20); // 0010 and PTS only
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
358 }
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
359 s->b_buffer_ptr = 12;
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
360 }
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
361 memcpy (s->b_buffer+s->b_buffer_ptr, s->buffer+ptr, len);
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
362 s->b_buffer_ptr += len;
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
363 }
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
364 }
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
365
9007
12fc55eb3373 Cleanup of the muxer API, func parameters muxer & muxer_f eliminated.
arpi
parents: 8585
diff changeset
366 static void mpegfile_write_header(muxer_t *muxer){
8585
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
367 unsigned int i;
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
368 size_t sz = MUXER_MPEG_BLOCKSIZE-24;
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
369 unsigned char buff[12];
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
370 muxer_stream_t *s = muxer->streams[0];
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
371 uint32_t l1;
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
372 uint16_t l2;
9007
12fc55eb3373 Cleanup of the muxer API, func parameters muxer & muxer_f eliminated.
arpi
parents: 8585
diff changeset
373 FILE *f = muxer->file;
8585
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
374
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
375 if (s == NULL)
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
376 return; // no streams!?
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
377 // packet header (0x1ba) -- rewrite first stream buffer
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
378 *(uint32_t *)buff = be2me_32 (0x1ba);
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
379 write_mpeg_ts (buff+4, MPEG_STARTSCR, 0x20); // 0010 -- pack
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
380 write_mpeg_rate (buff+9, muxer->sysrate);
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
381 fwrite (buff, 12, 1, f);
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
382 // start system stream (in own block): Sys (0x1bb)
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
383 l1 = be2me_32 (0x1bb);
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
384 l2 = be2me_16 (6 + 3*muxer->avih.dwStreams); // header_length
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
385 fwrite (&l1, 4, 1, f);
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
386 fwrite (&l2, 2, 1, f);
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
387 write_mpeg_rate (buff, muxer->sysrate); // rate_bound
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
388 // set number of audio/video, fixed_flag=CSPS_flag=system_*_lock_flag=0
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
389 buff[3] = (muxer->avih.dwStreams - muxer->num_videos) << 2; // audio_bound
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
390 buff[4] = muxer->num_videos | 0x20;
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
391 buff[5] = 0xff; // reserved_byte
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
392 fwrite (buff, 6, 1, f);
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
393 for (i = 0; i < muxer->avih.dwStreams; i++) {
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
394 buff[0] = ((char *)&muxer->streams[i]->ckid)[3]; // last char in big endian
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
395 //fprintf (stderr, "... stream 0x1%02x; bufsize %u", (int)buff[0], muxer->streams[i]->h.dwSuggestedBufferSize);
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
396 write_mpeg_std (buff+1, muxer->streams[i]->h.dwSuggestedBufferSize, 0xc0); // 11
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
397 fwrite (buff, 3, 1, f);
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
398 sz -= 3;
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
399 }
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
400 if (sz >= 6) { // padding block
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
401 l1 = be2me_32 (0x1be);
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
402 sz -= 6;
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
403 l2 = be2me_16 (sz);
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
404 fwrite (&l1, 4, 1, f);
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
405 fwrite (&l2, 2, 1, f);
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
406 }
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
407 s->b_buffer[0] = 0x0f; // end of list - next bit has to be 0
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
408 // stuFFing bytes -- rewrite first stream buffer
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
409 if (sz > 1)
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
410 memset (s->b_buffer+1, 0xff, sz-1);
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
411 fwrite (s->b_buffer, sz, 1, f);
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
412 muxer->movi_start = 0;
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
413 muxer->movi_end = MUXER_MPEG_BLOCKSIZE;
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
414 }
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
415
9007
12fc55eb3373 Cleanup of the muxer API, func parameters muxer & muxer_f eliminated.
arpi
parents: 8585
diff changeset
416 static void mpegfile_write_index(muxer_t *muxer){
8585
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
417 unsigned int i;
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
418 unsigned int rsr;
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
419
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
420 if (!muxer->avih.dwStreams) return; // no streams?!
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
421 // finish all but one video and audio streams
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
422 rsr = muxer->sysrate; // reserve it since it's silly change it at that point
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
423 for (i = 0; i < muxer->avih.dwStreams-1; i++)
9007
12fc55eb3373 Cleanup of the muxer API, func parameters muxer & muxer_f eliminated.
arpi
parents: 8585
diff changeset
424 write_mpeg_block (muxer, muxer->streams[i], muxer->file, NULL, 0, 0);
8585
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
425 // end sequence: ISO-11172-End (0x1b9) and finish very last block
9007
12fc55eb3373 Cleanup of the muxer API, func parameters muxer & muxer_f eliminated.
arpi
parents: 8585
diff changeset
426 write_mpeg_block (muxer, muxer->streams[i], muxer->file, NULL, 0, 1);
8585
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
427 //fprintf (stderr, "PTS to SCR delay: min %u.%03u, max %u.%03u\n",
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
428 // mpeg_min_delay/90000, (mpeg_min_delay/90)%1000,
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
429 // mpeg_max_delay/90000, (mpeg_max_delay/90)%1000);
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
430 muxer->sysrate = rsr;
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
431 }
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
432
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
433 void muxer_init_muxer_mpeg(muxer_t *muxer){
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
434 muxer->cont_new_stream = &mpegfile_new_stream;
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
435 muxer->cont_write_chunk = &mpegfile_write_chunk;
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
436 muxer->cont_write_header = &mpegfile_write_header;
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
437 muxer->cont_write_index = &mpegfile_write_index;
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
438 // mpeg_min_delay = mpeg_max_delay = MPEG_STARTPTS-MPEG_STARTSCR;
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
439 }
27da710563c2 the long-waited MUXER layer, and new MPEG-PS muxer
arpi
parents:
diff changeset
440