~ubuntu-branches/ubuntu/hardy/avidemux/hardy

« back to all changes in this revision

Viewing changes to avidemux/ADM_matroska/ADM_mkv.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Matvey Kozhev
  • Date: 2007-12-18 13:53:04 UTC
  • mfrom: (1.1.7 upstream)
  • Revision ID: james.westby@ubuntu.com-20071218135304-cdqec2lg2bglyz15
Tags: 1:2.4~preview3-0.0ubuntu1
* Upload to Ubuntu. (LP: #163287, LP: #126572)
* debian/changelog: re-added Ubuntu releases.
* debian/control:
  - Require debhelper >= 5.0.51 (for dh_icons) and imagemagick.
  - Build-depend on libsdl1.2-dev instead of libsdl-dev.
  - Build against newer libx264-dev. (LP: #138854)
  - Removed libamrnb-dev, not in Ubuntu yet.
* debian/rules:
  - Install all icon sizes, using convert (upstream installs none).
  - Added missing calls to dh_installmenu, dh_installman, dh_icons and
    dh_desktop.
* debian/menu, debian/avidemux-qt.menu:
  - Corrected package and executable names.
* debian/avidemux-common.install: Install icons.
* debian/avidemux.common.manpages: Install man/avidemux.1.
* debian/links, debian/avidemux-cli.links, debian/avidemux-gtk.links:
  - Link manpages to avidemux.1.gz.
* debian/install, debian/avidemux-qt.install, debian/avidemux-gtk.desktop,
  debian/avidemux-qt.desktop: Install desktop files.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/***************************************************************************
2
 
    copyright            : (C) 2006 by mean
3
 
    email                : fixounet@free.fr
4
 
 ***************************************************************************/
5
 
 
6
 
/***************************************************************************
7
 
 *                                                                         *
8
 
 *   This program is free software; you can redistribute it and/or modify  *
9
 
 *   it under the terms of the GNU General Public License as published by  *
10
 
 *   the Free Software Foundation; either version 2 of the License, or     *
11
 
 *   (at your option) any later version.                                   *
12
 
 *                                                                         *
13
 
 ***************************************************************************/
14
 
#include "config.h"
15
 
 
16
 
#include <stdio.h>
17
 
#include <stdlib.h>
18
 
 
19
 
#include <string.h>
20
 
 
21
 
#include "math.h"
22
 
 
23
 
#include "ADM_library/default.h"
24
 
#include "ADM_editor/ADM_Video.h"
25
 
#include <ADM_assert.h>
26
 
 
27
 
#include "ADM_library/fourcc.h"
28
 
#include "ADM_toolkit/toolkit.hxx"
29
 
 
30
 
#include "ADM_mkv.h"
31
 
 
32
 
extern "C"
33
 
{
34
 
#include "ADM_lavcodec/avcodec.h"
35
 
#include "ADM_lavformat/avformat.h"
36
 
};
37
 
 
38
 
#define CONTEXT ((AVFormatContext* )_context)
39
 
 
40
 
WAVHeader *mkvHeader::getAudioInfo(void )
41
 
{
42
 
  if(_curAudio) return _curAudio->getInfo();
43
 
  return NULL;
44
 
}
45
 
/*
46
 
    __________________________________________________________
47
 
*/
48
 
 
49
 
uint8_t mkvHeader::getAudioStream(AVDMGenericAudioStream **audio)
50
 
{
51
 
  if(_curAudio)
52
 
  {
53
 
    *audio=_curAudio;
54
 
    return 1;
55
 
  }
56
 
  *audio=NULL;
57
 
  return 0; 
58
 
}
59
 
/*
60
 
    __________________________________________________________
61
 
*/
62
 
 
63
 
void mkvHeader::Dump(void)
64
 
{
65
 
  printf("*********** MKV INFO***********\n");
66
 
  printf("[MKV] %d x %d, %d frames\n",
67
 
                 _mainaviheader.dwWidth,_mainaviheader.dwHeight,_mainaviheader.dwTotalFrames);
68
 
  printf("[MKV] We have %u bytes of extradata for video\n",_videoExtraLen);
69
 
  printf("[MKV] %u / %u\n",  _videostream.dwScale,  _videostream.dwRate);
70
 
  printf("[MKV] %u frames\n",_videostream.dwLength);
71
 
  for(int i=0;i<_nbAudioTrack;i++)
72
 
  {
73
 
    printf("[MKV] Track:%u index:%u fq:%u channels:%u codec:%u extradatalen:%u length:%u nbchunk %u\n"
74
 
            ,i,_audioTracks[i].streamIndex ,
75
 
            _audioTracks[i].wavHeader.frequency,
76
 
            _audioTracks[i].wavHeader.channels,
77
 
            _audioTracks[i].wavHeader.encoding,
78
 
            _audioTracks[i].extraDataLen,
79
 
            _audioTracks[i].length,
80
 
            _audioTracks[i].nbPackets);
81
 
    
82
 
  }
83
 
  printf("*********** MKV INFO***********\n");
84
 
}
85
 
/*
86
 
    __________________________________________________________
87
 
*/
88
 
 
89
 
uint32_t mkvHeader::getNbStream(void) 
90
 
{
91
 
  return _nbAudioTrack; 
92
 
}
93
 
/*
94
 
    __________________________________________________________
95
 
*/
96
 
 
97
 
uint8_t mkvHeader::close(void)
98
 
{
99
 
  if(_context)
100
 
  {
101
 
    av_close_input_file(CONTEXT);
102
 
    _context=NULL;
103
 
  }
104
 
  if(_audioTracks)
105
 
  {
106
 
    for(int i=0;i<_nbAudioTrack;i++)
107
 
    { 
108
 
      if(_audioTracks[i].extraData) delete []  _audioTracks[i].extraData;
109
 
      
110
 
    }
111
 
    delete _audioTracks;
112
 
    _audioTracks=NULL;
113
 
  }
114
 
  if(_videoExtraData)
115
 
  {
116
 
    delete [] _videoExtraData;
117
 
    _videoExtraData=NULL; 
118
 
  }
119
 
  if(myName)
120
 
  {
121
 
    delete [] myName;
122
 
    myName=NULL; 
123
 
  }
124
 
}
125
 
/*
126
 
    __________________________________________________________
127
 
*/
128
 
 
129
 
uint8_t mkvHeader::needDecompress(void)
130
 
{
131
 
  return 1; 
132
 
}
133
 
/*
134
 
    __________________________________________________________
135
 
*/
136
 
 
137
 
 mkvHeader::mkvHeader( void ) : vidHeader()
138
 
{
139
 
  _fd=NULL;
140
 
  _audioIndex=_videoIndex=-1;
141
 
  _context=NULL;
142
 
  _nbAudioTrack=0;
143
 
  _audioTracks=NULL;
144
 
  myName=NULL;
145
 
}
146
 
/*
147
 
    __________________________________________________________
148
 
*/
149
 
 
150
 
 mkvHeader::~mkvHeader(  )
151
 
{
152
 
  close();
153
 
}
154
 
/*
155
 
    __________________________________________________________
156
 
*/
157
 
 
158
 
uint8_t mkvHeader::open(char *name)
159
 
{
160
 
  int err;
161
 
  AVInputFormat *format;
162
 
  
163
 
  printf("[Matroska] Open\n");
164
 
  format= av_find_input_format("matroska");
165
 
  if(!format)
166
 
  {
167
 
    printf("[MKV] input format failed\n");
168
 
    return 0;
169
 
  }
170
 
  err = av_open_input_file((AVFormatContext **)&_context, name, format, 0, NULL);
171
 
  if (err < 0) {
172
 
    printf("[MKV] Error in open input file %d\n",err);
173
 
    return 0;
174
 
  }
175
 
  av_find_stream_info(CONTEXT);
176
 
  
177
 
  for(int i = 0; i < CONTEXT->nb_streams; i++) {
178
 
    AVCodecContext *enc = CONTEXT->streams[i]->codec;
179
 
    switch(enc->codec_type) {
180
 
      case CODEC_TYPE_AUDIO:
181
 
        _nbAudioTrack++;
182
 
        printf("[MKV] %d is audio\n",i,CONTEXT->nb_streams);
183
 
        break;
184
 
      case CODEC_TYPE_VIDEO:
185
 
        _videoIndex=i;
186
 
        printf("[MKV] %d is video\n",i,CONTEXT->nb_streams);
187
 
        break;
188
 
      default:
189
 
        break;
190
 
    }
191
 
  }
192
 
  if(_videoIndex<0)
193
 
  {
194
 
    printf("[MKV] No video track found\n");
195
 
    return 0; 
196
 
  }
197
 
  if(_nbAudioTrack)
198
 
  {
199
 
    int cur=0;
200
 
    _audioTracks=new mkvAudioTrak[ _nbAudioTrack];
201
 
    memset(_audioTracks,0,sizeof(mkvAudioTrak) *_nbAudioTrack);
202
 
    for(int i = 0; i < CONTEXT->nb_streams; i++) 
203
 
    {
204
 
      AVCodecContext *enc = CONTEXT->streams[i]->codec;
205
 
      switch(enc->codec_type) 
206
 
      {
207
 
        case CODEC_TYPE_AUDIO:
208
 
          _audioTracks[cur++].streamIndex=i;
209
 
          break;
210
 
        default:
211
 
          break;
212
 
      }
213
 
    }
214
 
    
215
 
  }
216
 
  
217
 
  if(!readVideoInfo())
218
 
  {
219
 
    printf("[MKV] Failed reading video info\n");
220
 
    return 0; 
221
 
  }
222
 
  myName=ADM_strdup(name);
223
 
  prebuildIndex();
224
 
 
225
 
  for(int i=0;i<_nbAudioTrack;i++)
226
 
  {
227
 
    readAudioInfo(i); 
228
 
  }
229
 
  if(_nbAudioTrack)
230
 
  {
231
 
    printf("[MKV] Building current audio track\n");
232
 
    _isaudiopresent=1;
233
 
    _curAudio=new mkvAudio(name,&_audioTracks[0]);
234
 
  }
235
 
  printf("[MKV] Successfully open\n");
236
 
  
237
 
  Dump();
238
 
  return 1;
239
 
}
240
 
/*
241
 
    __________________________________________________________
242
 
*/
243
 
 
244
 
 uint8_t  mkvHeader::prebuildIndex(void)
245
 
{
246
 
  AVPacket pkt1, *pkt = &pkt1;
247
 
  int ret;
248
 
  int nbVideo=0;
249
 
  printf("\n[MKV]Preindexing started, that can take a while...\n");
250
 
  while(1)
251
 
  {
252
 
    ret = av_read_frame(CONTEXT, pkt);
253
 
    if (ret < 0) 
254
 
    {
255
 
      break;
256
 
    }
257
 
    if(pkt->stream_index==_videoIndex) 
258
 
    {
259
 
      nbVideo++;
260
 
    }
261
 
    for(int i=0;i<_nbAudioTrack;i++)
262
 
    {
263
 
      if( pkt->stream_index==_audioTracks[i].streamIndex)
264
 
      {
265
 
        _audioTracks[i].nbPackets++;
266
 
        _audioTracks[i].length+=pkt->size;
267
 
      }
268
 
    }
269
 
  }
270
 
  printf("\n[MKV]Preindexing done\n");
271
 
  _videostream.dwLength=_mainaviheader.dwTotalFrames=nbVideo;
272
 
  
273
 
  rewind();
274
 
        
275
 
        
276
 
  return 1;
277
 
}
278
 
uint8_t mkvHeader::rewind( void )
279
 
{
280
 
  int err;
281
 
  AVInputFormat *format;
282
 
  
283
 
  
284
 
  format= av_find_input_format("matroska");
285
 
  av_close_input_file(CONTEXT);
286
 
  _context=NULL;
287
 
  err = av_open_input_file((AVFormatContext **)&_context, myName, format, 0, NULL);
288
 
  ADM_assert(err>=0);
289
 
  return 1;
290
 
}
291
 
/*
292
 
    __________________________________________________________
293
 
*/
294
 
 
295
 
  uint8_t  mkvHeader::setFlag(uint32_t frame,uint32_t flags)
296
 
{
297
 
  return 0; 
298
 
}
299
 
/*
300
 
    __________________________________________________________
301
 
*/
302
 
 
303
 
uint32_t mkvHeader::getFlags(uint32_t frame,uint32_t *flags)
304
 
{
305
 
  *flags=AVI_KEY_FRAME;
306
 
  return 1; 
307
 
}
308
 
/*
309
 
    __________________________________________________________
310
 
*/
311
 
 
312
 
uint8_t  mkvHeader::getFrameNoAlloc(uint32_t framenum,uint8_t *ptr,uint32_t* framelen,
313
 
                                     uint32_t *flags)
314
 
{
315
 
  AVPacket pkt1, *pkt = &pkt1;
316
 
  int ret;
317
 
  if(!framenum) rewind();
318
 
  while(1)
319
 
  {
320
 
    ret = av_read_frame(CONTEXT, pkt);
321
 
    if (ret < 0) 
322
 
    {
323
 
      printf("[MKV] Error reading frame %d\n",framenum);
324
 
      return 0;
325
 
    }
326
 
    if(pkt->stream_index!=_videoIndex) 
327
 
    {
328
 
      //printf("[MKV] Wrong stream %u %u\n",pkt->stream_index,_videoIndex);
329
 
      continue;
330
 
    }
331
 
    memcpy(ptr,pkt->data,pkt->size);
332
 
    *framelen=pkt->size;
333
 
    if(flags)
334
 
    {
335
 
      if(pkt->flags  &  PKT_FLAG_KEY)
336
 
        *flags=AVI_KEY_FRAME;
337
 
      else
338
 
        *flags=0;
339
 
    }
340
 
    break;
341
 
  }
342
 
  return 1; 
343
 
}
344
 
/*
345
 
    __________________________________________________________
346
 
*/
347
 
 
348
 
uint8_t  mkvHeader::getFrameNoAlloc(uint32_t framenum,uint8_t *ptr,uint32_t* framelen)
349
 
{
350
 
  uint32_t flags;
351
 
  return getFrameNoAlloc(framenum,ptr,framelen,&flags); 
352
 
}
353
 
/*
354
 
    Read info, fill in mainaviheader & video streamheader
355
 
    __________________________________________________________
356
 
*/
357
 
uint8_t mkvHeader::readVideoInfo( void)
358
 
{
359
 
  AVCodecContext *enc=CONTEXT->streams[_videoIndex]->codec;
360
 
  uint32_t nbFrame;
361
 
  if(!enc) 
362
 
  {
363
 
    printf("[MKV]Failed to get video\n");
364
 
    return 0;
365
 
  }
366
 
  _isvideopresent=1;
367
 
  memset(&_mainaviheader,0,sizeof(_mainaviheader));
368
 
  _mainaviheader.dwWidth=enc->width;
369
 
  _mainaviheader.dwHeight=enc->height;
370
 
  _video_bih.biWidth=enc->width;
371
 
  _video_bih.biHeight=enc->height;
372
 
  
373
 
 
374
 
  uint32_t fcc=0;
375
 
  // Set codec
376
 
  switch(enc->codec_id)
377
 
  {
378
 
    case CODEC_ID_H264:      fcc=fourCC::get((uint8_t *)"H264");break; 
379
 
    case CODEC_ID_MPEG4:     fcc=fourCC::get((uint8_t *)"DIVX");break;
380
 
    case CODEC_ID_MSMPEG4V3: fcc=fourCC::get((uint8_t *)"DIV3");break;
381
 
    default:
382
 
      printf("[MKV] Unknown video fourcc %d\n",enc->codec_id);
383
 
      return 0;
384
 
  }
385
 
  _video_bih.biCompression=_videostream.fccHandler=fcc;
386
 
  // Extradata ?
387
 
  if(enc->extradata && enc->extradata_size )
388
 
  {
389
 
    _videoExtraData=new uint8_t[enc->extradata_size];
390
 
    _videoExtraLen= enc->extradata_size;
391
 
    memcpy(_videoExtraData,enc->extradata,_videoExtraLen);
392
 
    
393
 
    
394
 
  }
395
 
  // FrameRate, frame count
396
 
  AVRational r=CONTEXT->streams[_videoIndex]->r_frame_rate;
397
 
  if(r.num && r.den)
398
 
  {
399
 
    _videostream.dwScale=r.num;
400
 
    _videostream.dwRate=r.den;
401
 
  }else
402
 
  {
403
 
    _videostream.dwScale=1000;
404
 
    _videostream.dwRate=25000;
405
 
   
406
 
  }
407
 
  //
408
 
  _videostream.dwLength=_mainaviheader.dwTotalFrames=5;
409
 
  printf("[MKV] Video info ok\n");
410
 
  Dump();
411
 
  return 1;
412
 
}
413
 
/*
414
 
    __________________________________________________________
415
 
*/
416
 
 
417
 
uint8_t mkvHeader::readAudioInfo( uint32_t track)
418
 
{
419
 
  int index=_audioTracks[track].streamIndex;
420
 
  WAVHeader *hdr=&(_audioTracks[track].wavHeader);
421
 
  AVCodecContext *enc=CONTEXT->streams[index]->codec;
422
 
  if(!enc) 
423
 
  {
424
 
    printf("[MKV]Failed to get audio for track %d (track index %d)\n",track,index);
425
 
    return 0;
426
 
  }
427
 
  // Set codec
428
 
  switch(enc->codec_id)
429
 
  {
430
 
    case CODEC_ID_MPEG4AAC:
431
 
    case CODEC_ID_AAC: hdr->encoding=WAV_AAC;break; 
432
 
    case CODEC_ID_MP3: hdr->encoding=WAV_MP3;break; 
433
 
    case CODEC_ID_AC3: hdr->encoding=WAV_AC3;break; 
434
 
    case CODEC_ID_VORBIS: hdr->encoding=WAV_OGG;break; 
435
 
    default:
436
 
      printf("[MKV] Unknown audio fourcc %d\n",enc->codec_id);
437
 
      hdr->encoding=WAV_UNKNOWN;
438
 
      return 0;
439
 
  }
440
 
  // Extradata ?
441
 
  if(enc->extradata && enc->extradata_size )
442
 
  {
443
 
    _audioTracks[track].extraData=new uint8_t[enc->extradata_size];
444
 
    _audioTracks[track].extraDataLen= enc->extradata_size;
445
 
    memcpy(_audioTracks[track].extraData,enc->extradata,_audioTracks[track].extraDataLen);
446
 
  }
447
 
  // Channels fq etc...
448
 
  hdr->frequency=enc->sample_rate;
449
 
  hdr->channels=enc->channels;
450
 
  hdr->byterate=(enc->bit_rate>>3);
451
 
  if(!hdr->byterate) hdr->byterate=128000>>3;
452
 
 
453
 
  
454
 
  printf("[MKV] Video audio ok for track %d\n",track);
455
 
 
456
 
  return 1;
457
 
}
458
 
 
459
 
//EOF