~ubuntu-branches/ubuntu/feisty/avidemux/feisty

« back to all changes in this revision

Viewing changes to avidemux/ADM_mplex/ADM_mplexmuxer.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Daniel T Chen
  • Date: 2006-12-15 17:13:20 UTC
  • mfrom: (1.1.6 upstream)
  • Revision ID: james.westby@ubuntu.com-20061215171320-w79pvpehxx2fr217
Tags: 1:2.3.0-0.0ubuntu1
* Merge from debian-multimedia.org, remaining Ubuntu change:
  - desktop file,
  - no support for ccache and make -j.
* Closes Ubuntu: #69614.

Show diffs side-by-side

added added

removed removed

Lines of Context:
23
23
 
24
24
#include "config.h"
25
25
 
26
 
#ifdef CYG_MANGLING
27
 
#define WIN32_CLASH
28
 
#define WAIT1() ADM_usleep(1000) // Allow slave thread to start
29
 
#else
30
 
#define WAIT1() sleep(1)
31
 
#endif
32
 
 
33
26
#include <stdio.h>
34
27
#include <stdlib.h>
35
28
#include <math.h>
36
29
#include <string.h>
37
30
#include <sys/stat.h>
38
31
#include <pthread.h>
39
 
 
 
32
#define WIN32_CLASH
40
33
#include "interact.hpp"
41
34
 
42
35
#undef malloc
86
79
/***************************************************************************/
87
80
 
88
81
 
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;
97
90
 
98
91
static  vector<IBitStream *> inputs;
99
92
 
100
 
static int slaveThread( void );
 
93
static int slaveThread( WAVHeader *audioheader );
101
94
 
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;
120
113
        close();
121
114
}
122
115
//___________________________________________________________________________
 
116
uint8_t mplexMuxer::audioEof(void)
 
117
{
 
118
        channelaudio->Abort();
 
119
}
 
120
uint8_t mplexMuxer::videoEof(void)
 
121
{
 
122
  channelvideo->Abort();
 
123
}
 
124
 
 
125
//___________________________________________________________________________
123
126
uint8_t mplexMuxer::open(const char *filename, uint32_t inbitrate,ADM_MUXER_TYPE type, aviInfo *info, WAVHeader *audioheader)
124
127
{
125
128
        printf("Opening mplex muxer (%s)\n",filename);
126
129
        _running=1;
127
 
     
128
 
        channelaudio=new Transfert();
129
 
        channelvideo=new Transfert();
 
130
 
 
131
        
 
132
        channelaudio=new PacketQueue(  "Mplex audioQ",TRANSFERT_SLOT,TRANSFERT_BUFFER);
 
133
        channelvideo=new PacketQueue(  "Mplex videoQ",TRANSFERT_SLOT,TRANSFERT_BUFFER);
130
134
        
131
135
        outputStream=new FileOutputStream ( filename );
132
136
        
149
153
        
150
154
        pthread_t slave;
151
155
        slaveRunning=1;
152
 
        ADM_assert(!pthread_create(&slave,NULL,(THRINP)slaveThread,NULL));
 
156
        ADM_assert(!pthread_create(&slave,NULL,(THRINP)slaveThread,audioheader));
153
157
 
154
 
        WAIT1();        
 
158
        ADM_usleep(1000*50); // Allow slave thread to start
155
159
        
156
160
        printf("Init ok\n");
157
161
        return 1;
158
162
}
159
 
int slaveThread( void )
 
163
static uint8_t wavToStreamType(WAVHeader *hdr,mplexStreamDescriptor *desc)
 
164
{
 
165
    ADM_assert(hdr);
 
166
    desc->frequency=hdr->frequency;
 
167
    desc->channel=hdr->channels;
 
168
    switch(hdr->encoding)
 
169
    {
 
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;
 
174
        default: return 0;
 
175
    }
 
176
  return 1;
 
177
}
 
178
extern const char *getStrFromAudioCodec( uint32_t codec);
 
179
int slaveThread( WAVHeader *audioheader )
160
180
{
161
181
        MultiplexJob job;
162
 
        printf("Slave thread : creating job & muxer\n");
 
182
        mplexStreamDescriptor audioDesc;
 
183
        mplexStreamDescriptor videoDesc;
 
184
 
 
185
        printf("[Muxer Slave Thread] Slave thread : creating job & muxer\n");
163
186
 
164
187
        
165
188
        printf("output file created\n");
166
 
        
167
 
        audioin=new IFileBitStream(channelaudio);
168
 
        
169
 
        printf("audio done, creating video bitstream\n");
170
 
        videoin=new IFileBitStream(channelvideo);
 
189
        wavToStreamType(audioheader,&audioDesc);
 
190
        audioin=new IFileBitStream(channelaudio,&audioDesc);
 
191
        
 
192
        printf("audio done (%s), creating video bitstream\n",getStrFromAudioCodec(audioheader->encoding));
 
193
        videoDesc.kind=MPEG_VIDEO;
 
194
        videoin=new IFileBitStream(channelvideo,&videoDesc);
171
195
        
172
196
        printf("Both stream ready\n");
173
197
         
191
215
uint8_t mplexMuxer::writeAudioPacket(uint32_t len, uint8_t *buf)
192
216
{
193
217
        
194
 
        return channelaudio->write(buf,len);
 
218
        return channelaudio->Push(buf,len,0);
195
219
}
196
220
//___________________________________________________________________________
197
221
uint8_t mplexMuxer::needAudio( void )
198
222
{
199
223
        
200
 
       return channelaudio->needData();
 
224
       return 1;
201
225
}
202
226
static uint8_t seq_start_code [] = {0x00, 0x00, 0x01, 0xB3};
203
227
static uint8_t gop_start_code [] = {0x00, 0x00, 0x01, 0xB8};
204
228
 
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)
207
231
{
208
232
uint8_t r=0;   
209
233
uint16_t a1,a2,a3,a4,ff;           
210
234
        if(_restamp) // restamp timecode ?
211
235
        {
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) )
213
237
                {
214
238
                        uint8_t *ptr;
215
239
                        uint32_t size;
216
240
                        
217
 
                        ptr=buf;
218
 
                        size=len;
 
241
                        ptr=bitstream->data;
 
242
                        size=bitstream->len;
219
243
                        // There is a gop a or seq header
220
 
                        if(buf[3]==0xb3) // Seq
 
244
                        if(bitstream->data[3]==0xb3) // Seq
221
245
                        {
222
246
                                while((ptr[0] || ptr[1] || ptr[2]!=1 || ptr[3]!=0xB8 ) && size>0)
223
247
                                {
233
257
                        else
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;
238
262
                                
239
263
                                ptr+=4; // skip gop header go to timestamp
291
315
        
292
316
                }
293
317
        }
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();
298
 
        }
299
 
        if(channelvideo->fillingUp())
300
 
        {
301
 
                //printf("Output buffer filling up, sleeping a bit\n");
302
 
                channelvideo->clientLock();
303
 
        }                
304
 
        
 
318
 
 
319
        if( cond_slaveThread_problem->iswaiting() )
 
320
        {
 
321
               kind_of_slaveThread_problem_rc = DIA_quota(kind_of_slaveThread_problem);
 
322
               cond_slaveThread_problem->wakeup();
 
323
         }
 
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;
 
330
 
 
331
        while(len)
 
332
        {
 
333
          if(len>INPUT_MAX_BLOCK)
 
334
          {
 
335
              channelvideo->Push(ptr,INPUT_MAX_BLOCK,0);
 
336
              len-=INPUT_MAX_BLOCK;
 
337
              ptr+=INPUT_MAX_BLOCK;
 
338
          }
 
339
          else
 
340
          {
 
341
            channelvideo->Push(ptr,len,0);
 
342
            len=0;
 
343
          }
 
344
        }
305
345
        return 1;
306
346
}
307
347
//___________________________________________________________________________
316
356
        if(_running)
317
357
        {
318
358
                _running=0;
319
 
                channelvideo->abort();
320
 
                channelaudio->abort();
 
359
                channelvideo->Abort();
 
360
                channelaudio->Abort();
321
361
                while(slaveRunning)
322
362
                {
323
363
                        printf("Waiting for slave thread to end\n");
324
 
                        WAIT1();
 
364
                        ADM_usleep(100*1000);
325
365
                }
326
366
                        // Flush
327
367
                        // Cause deadlock :