1
/***************************************************************************
2
copyright : (C) 2006 by mean
3
email : fixounet@free.fr
4
***************************************************************************/
6
/***************************************************************************
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. *
13
***************************************************************************/
23
#include "ADM_library/default.h"
24
#include "ADM_editor/ADM_Video.h"
25
#include <ADM_assert.h>
27
#include "ADM_library/fourcc.h"
28
#include "ADM_toolkit/toolkit.hxx"
34
#include "ADM_lavcodec/avcodec.h"
35
#include "ADM_lavformat/avformat.h"
38
#define CONTEXT ((AVFormatContext* )_context)
40
WAVHeader *mkvHeader::getAudioInfo(void )
42
if(_curAudio) return _curAudio->getInfo();
46
__________________________________________________________
49
uint8_t mkvHeader::getAudioStream(AVDMGenericAudioStream **audio)
60
__________________________________________________________
63
void mkvHeader::Dump(void)
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++)
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);
83
printf("*********** MKV INFO***********\n");
86
__________________________________________________________
89
uint32_t mkvHeader::getNbStream(void)
94
__________________________________________________________
97
uint8_t mkvHeader::close(void)
101
av_close_input_file(CONTEXT);
106
for(int i=0;i<_nbAudioTrack;i++)
108
if(_audioTracks[i].extraData) delete [] _audioTracks[i].extraData;
116
delete [] _videoExtraData;
117
_videoExtraData=NULL;
126
__________________________________________________________
129
uint8_t mkvHeader::needDecompress(void)
134
__________________________________________________________
137
mkvHeader::mkvHeader( void ) : vidHeader()
140
_audioIndex=_videoIndex=-1;
147
__________________________________________________________
150
mkvHeader::~mkvHeader( )
155
__________________________________________________________
158
uint8_t mkvHeader::open(char *name)
161
AVInputFormat *format;
163
printf("[Matroska] Open\n");
164
format= av_find_input_format("matroska");
167
printf("[MKV] input format failed\n");
170
err = av_open_input_file((AVFormatContext **)&_context, name, format, 0, NULL);
172
printf("[MKV] Error in open input file %d\n",err);
175
av_find_stream_info(CONTEXT);
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:
182
printf("[MKV] %d is audio\n",i,CONTEXT->nb_streams);
184
case CODEC_TYPE_VIDEO:
186
printf("[MKV] %d is video\n",i,CONTEXT->nb_streams);
194
printf("[MKV] No video track found\n");
200
_audioTracks=new mkvAudioTrak[ _nbAudioTrack];
201
memset(_audioTracks,0,sizeof(mkvAudioTrak) *_nbAudioTrack);
202
for(int i = 0; i < CONTEXT->nb_streams; i++)
204
AVCodecContext *enc = CONTEXT->streams[i]->codec;
205
switch(enc->codec_type)
207
case CODEC_TYPE_AUDIO:
208
_audioTracks[cur++].streamIndex=i;
219
printf("[MKV] Failed reading video info\n");
222
myName=ADM_strdup(name);
225
for(int i=0;i<_nbAudioTrack;i++)
231
printf("[MKV] Building current audio track\n");
233
_curAudio=new mkvAudio(name,&_audioTracks[0]);
235
printf("[MKV] Successfully open\n");
241
__________________________________________________________
244
uint8_t mkvHeader::prebuildIndex(void)
246
AVPacket pkt1, *pkt = &pkt1;
249
printf("\n[MKV]Preindexing started, that can take a while...\n");
252
ret = av_read_frame(CONTEXT, pkt);
257
if(pkt->stream_index==_videoIndex)
261
for(int i=0;i<_nbAudioTrack;i++)
263
if( pkt->stream_index==_audioTracks[i].streamIndex)
265
_audioTracks[i].nbPackets++;
266
_audioTracks[i].length+=pkt->size;
270
printf("\n[MKV]Preindexing done\n");
271
_videostream.dwLength=_mainaviheader.dwTotalFrames=nbVideo;
278
uint8_t mkvHeader::rewind( void )
281
AVInputFormat *format;
284
format= av_find_input_format("matroska");
285
av_close_input_file(CONTEXT);
287
err = av_open_input_file((AVFormatContext **)&_context, myName, format, 0, NULL);
292
__________________________________________________________
295
uint8_t mkvHeader::setFlag(uint32_t frame,uint32_t flags)
300
__________________________________________________________
303
uint32_t mkvHeader::getFlags(uint32_t frame,uint32_t *flags)
305
*flags=AVI_KEY_FRAME;
309
__________________________________________________________
312
uint8_t mkvHeader::getFrameNoAlloc(uint32_t framenum,uint8_t *ptr,uint32_t* framelen,
315
AVPacket pkt1, *pkt = &pkt1;
317
if(!framenum) rewind();
320
ret = av_read_frame(CONTEXT, pkt);
323
printf("[MKV] Error reading frame %d\n",framenum);
326
if(pkt->stream_index!=_videoIndex)
328
//printf("[MKV] Wrong stream %u %u\n",pkt->stream_index,_videoIndex);
331
memcpy(ptr,pkt->data,pkt->size);
335
if(pkt->flags & PKT_FLAG_KEY)
336
*flags=AVI_KEY_FRAME;
345
__________________________________________________________
348
uint8_t mkvHeader::getFrameNoAlloc(uint32_t framenum,uint8_t *ptr,uint32_t* framelen)
351
return getFrameNoAlloc(framenum,ptr,framelen,&flags);
354
Read info, fill in mainaviheader & video streamheader
355
__________________________________________________________
357
uint8_t mkvHeader::readVideoInfo( void)
359
AVCodecContext *enc=CONTEXT->streams[_videoIndex]->codec;
363
printf("[MKV]Failed to get video\n");
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;
376
switch(enc->codec_id)
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;
382
printf("[MKV] Unknown video fourcc %d\n",enc->codec_id);
385
_video_bih.biCompression=_videostream.fccHandler=fcc;
387
if(enc->extradata && enc->extradata_size )
389
_videoExtraData=new uint8_t[enc->extradata_size];
390
_videoExtraLen= enc->extradata_size;
391
memcpy(_videoExtraData,enc->extradata,_videoExtraLen);
395
// FrameRate, frame count
396
AVRational r=CONTEXT->streams[_videoIndex]->r_frame_rate;
399
_videostream.dwScale=r.num;
400
_videostream.dwRate=r.den;
403
_videostream.dwScale=1000;
404
_videostream.dwRate=25000;
408
_videostream.dwLength=_mainaviheader.dwTotalFrames=5;
409
printf("[MKV] Video info ok\n");
414
__________________________________________________________
417
uint8_t mkvHeader::readAudioInfo( uint32_t track)
419
int index=_audioTracks[track].streamIndex;
420
WAVHeader *hdr=&(_audioTracks[track].wavHeader);
421
AVCodecContext *enc=CONTEXT->streams[index]->codec;
424
printf("[MKV]Failed to get audio for track %d (track index %d)\n",track,index);
428
switch(enc->codec_id)
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;
436
printf("[MKV] Unknown audio fourcc %d\n",enc->codec_id);
437
hdr->encoding=WAV_UNKNOWN;
441
if(enc->extradata && enc->extradata_size )
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);
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;
454
printf("[MKV] Video audio ok for track %d\n",track);