86
79
/***************************************************************************/
89
static Transfert *channelaudio=NULL;
90
static Transfert *channelvideo=NULL;
82
static PacketQueue *channelaudio=NULL;
83
static PacketQueue *channelvideo=NULL;
91
84
static FileOutputStream *outputStream=NULL;
92
85
static IFileBitStream *audioin=NULL;
93
86
static IFileBitStream *videoin=NULL;
98
91
static vector<IBitStream *> inputs;
100
static int slaveThread( void );
93
static int slaveThread( WAVHeader *audioheader );
102
admMutex mutex_slaveThread_problem;
95
admMutex mutex_slaveThread_problem("mutex_slaveThread_problem");
103
96
admCond *cond_slaveThread_problem;
104
97
char * kind_of_slaveThread_problem;
105
98
unsigned int kind_of_slaveThread_problem_rc;
122
115
//___________________________________________________________________________
116
uint8_t mplexMuxer::audioEof(void)
118
channelaudio->Abort();
120
uint8_t mplexMuxer::videoEof(void)
122
channelvideo->Abort();
125
//___________________________________________________________________________
123
126
uint8_t mplexMuxer::open(const char *filename, uint32_t inbitrate,ADM_MUXER_TYPE type, aviInfo *info, WAVHeader *audioheader)
125
128
printf("Opening mplex muxer (%s)\n",filename);
128
channelaudio=new Transfert();
129
channelvideo=new Transfert();
132
channelaudio=new PacketQueue( "Mplex audioQ",TRANSFERT_SLOT,TRANSFERT_BUFFER);
133
channelvideo=new PacketQueue( "Mplex videoQ",TRANSFERT_SLOT,TRANSFERT_BUFFER);
131
135
outputStream=new FileOutputStream ( filename );
152
ADM_assert(!pthread_create(&slave,NULL,(THRINP)slaveThread,NULL));
156
ADM_assert(!pthread_create(&slave,NULL,(THRINP)slaveThread,audioheader));
158
ADM_usleep(1000*50); // Allow slave thread to start
156
160
printf("Init ok\n");
159
int slaveThread( void )
163
static uint8_t wavToStreamType(WAVHeader *hdr,mplexStreamDescriptor *desc)
166
desc->frequency=hdr->frequency;
167
desc->channel=hdr->channels;
168
switch(hdr->encoding)
170
case WAV_LPCM: desc->kind= LPCM_AUDIO;break;
171
case WAV_AC3: desc->kind= AC3_AUDIO;;break;
172
case WAV_MP2: case WAV_MP3: desc->kind= MPEG_AUDIO;;break;
173
case WAV_DTS: desc->kind= DTS_AUDIO;;break;
178
extern const char *getStrFromAudioCodec( uint32_t codec);
179
int slaveThread( WAVHeader *audioheader )
161
181
MultiplexJob job;
162
printf("Slave thread : creating job & muxer\n");
182
mplexStreamDescriptor audioDesc;
183
mplexStreamDescriptor videoDesc;
185
printf("[Muxer Slave Thread] Slave thread : creating job & muxer\n");
165
188
printf("output file created\n");
167
audioin=new IFileBitStream(channelaudio);
169
printf("audio done, creating video bitstream\n");
170
videoin=new IFileBitStream(channelvideo);
189
wavToStreamType(audioheader,&audioDesc);
190
audioin=new IFileBitStream(channelaudio,&audioDesc);
192
printf("audio done (%s), creating video bitstream\n",getStrFromAudioCodec(audioheader->encoding));
193
videoDesc.kind=MPEG_VIDEO;
194
videoin=new IFileBitStream(channelvideo,&videoDesc);
172
196
printf("Both stream ready\n");
191
215
uint8_t mplexMuxer::writeAudioPacket(uint32_t len, uint8_t *buf)
194
return channelaudio->write(buf,len);
218
return channelaudio->Push(buf,len,0);
196
220
//___________________________________________________________________________
197
221
uint8_t mplexMuxer::needAudio( void )
200
return channelaudio->needData();
202
226
static uint8_t seq_start_code [] = {0x00, 0x00, 0x01, 0xB3};
203
227
static uint8_t gop_start_code [] = {0x00, 0x00, 0x01, 0xB8};
205
229
//___________________________________________________________________________
206
uint8_t mplexMuxer::writeVideoPacket(uint32_t len, uint8_t *buf,uint32_t frameno,uint32_t displayframe)
230
uint8_t mplexMuxer::writeVideoPacket(ADMBitstream *bitstream)
209
233
uint16_t a1,a2,a3,a4,ff;
210
234
if(_restamp) // restamp timecode ?
212
if ( !memcmp(buf, seq_start_code, 4) || !memcmp(buf, gop_start_code, 4) )
236
if ( !memcmp(bitstream->data, seq_start_code, 4) || !memcmp(bitstream->data, gop_start_code, 4) )
219
243
// There is a gop a or seq header
220
if(buf[3]==0xb3) // Seq
244
if(bitstream->data[3]==0xb3) // Seq
222
246
while((ptr[0] || ptr[1] || ptr[2]!=1 || ptr[3]!=0xB8 ) && size>0)
234
258
{ // Now we are at gop start with a packet size
235
259
// Compute the current gop timestamp
236
double newtime=displayframe;
260
double newtime=bitstream->ptsFrame;
237
261
uint32_t hh,mm,ss,ms;
239
263
ptr+=4; // skip gop header go to timestamp
294
r= channelvideo->write(buf,len);
295
if( cond_slaveThread_problem->iswaiting() ){
296
kind_of_slaveThread_problem_rc = DIA_quota(kind_of_slaveThread_problem);
297
cond_slaveThread_problem->wakeup();
299
if(channelvideo->fillingUp())
301
//printf("Output buffer filling up, sleeping a bit\n");
302
channelvideo->clientLock();
319
if( cond_slaveThread_problem->iswaiting() )
321
kind_of_slaveThread_problem_rc = DIA_quota(kind_of_slaveThread_problem);
322
cond_slaveThread_problem->wakeup();
324
// Check for overflow
325
// Should not happen on audio
326
#warning the value is set also in mplex as BitStreamBuffering::BUFFER_SIZE
327
#define INPUT_MAX_BLOCK (64*1024-1)
328
uint8_t *ptr=bitstream->data;
329
uint32_t len=bitstream->len;
333
if(len>INPUT_MAX_BLOCK)
335
channelvideo->Push(ptr,INPUT_MAX_BLOCK,0);
336
len-=INPUT_MAX_BLOCK;
337
ptr+=INPUT_MAX_BLOCK;
341
channelvideo->Push(ptr,len,0);
307
347
//___________________________________________________________________________