PDA

View Full Version : How to get the avc1 raw data from ,mp4 container?About Bento4


xiaoqin99
27th August 2008, 08:52
:helpful:Now i study the Bento4(http://bento4.sourceforge.net/docs/html/index.html)
I try to get the avc1 raw data from the .mp4 file.Added the pps and sps into
.h264,the .h264 file is flushing when play it in vlc. please give me some advise.

There are my code.

/*****************************************************************
|
| AP4 - MP4 to PPM File Converter
|
|
****************************************************************/

/*----------------------------------------------------------------------
| includes
+---------------------------------------------------------------------*/
#include <stdio.h>
#include <stdlib.h>


/*----------------------------------------------------------------------
| includes writer header
+---------------------------------------------------------------------*/
#include "Ap4.h"



/*----------------------------------------------------------------------
| constants
+---------------------------------------------------------------------*/
#define BANNER "MP4 To PPM File Converter - Version 0.1a\n"\

#define AUDIO_HEADER_LEN 7

#define VIDEO_HEADER_LEN 4


/*----------------------------------------------------------------------
| PrintUsageAndExit
+---------------------------------------------------------------------*/
static void
PrintUsageAndExit()
{
fprintf(stderr,
BANNER
"\n\nusage: mp42aac [options] <inputfile> <outputfile><filebyte>\n");
exit(1);
}

/*----------------------------------------------------------------------
| WriteAdtsHeader
+---------------------------------------------------------------------*/
static AP4_Result
AudioAdtsHeader( unsigned int frame_size,char* audioHeader)
{
if (audioHeader == NULL)
{
return AP4_FAILURE;
}
unsigned char* bits = (unsigned char*)audioHeader;

bits[0] = 0xFF;
bits[1] = 0xF1; // 0xF9 (MPEG2)
bits[2] = 0x50;
bits[3] = 0x80 | ((frame_size+7) >> 11);
bits[4] = ((frame_size+7) >> 3)&0xFF;
bits[5] = (((frame_size+7) << 5)&0xFF) | 0x1F;
bits[6] = 0xFC;
return AP4_SUCCESS;

/*
0: syncword 12 always: '111111111111'
12: ID 1 0: MPEG-4, 1: MPEG-2
13: layer 2 always: '00'
15: protection_absent 1
16: profile 2
18: sampling_frequency_index 4
22: private_bit 1
23: channel_configuration 3
26: original/copy 1
27: home 1
28: emphasis 2 only if ID == 0

ADTS Variable header: these can change from frame to frame
28: copyright_identification_bit 1
29: copyright_identification_start 1
30: aac_frame_length 13 length of the frame including header (in bytes)
43: adts_buffer_fullness 11 0x7FF indicates VBR
54: no_raw_data_blocks_in_frame 2
ADTS Error check
crc_check 16 only if protection_absent == 0
*/
}

static AP4_Result
WriterAvccHeader(AP4_ByteStream* output)
{
unsigned char bits[4];

bits[0] = 0x00;
bits[1] = 0x00;
bits[2] = 0x00;
bits[3] = 0x01 ;

return output->Write(bits, 4);

}




/*----------------------------------------------------------------------
| main
+---------------------------------------------------------------------*/
int
main(int argc, char** argv)
{
if (argc < 3) {
PrintUsageAndExit();
}

// create the input stream
AP4_ByteStream* input =
new AP4_FileByteStream(argv[1],
AP4_FileByteStream::STREAM_MODE_READ);

//create the output stream
AP4_ByteStream* output =
new AP4_FileByteStream(argv[2],
AP4_FileByteStream::STREAM_MODE_WRITE);




// open the file
AP4_File* input_file = new AP4_File(*input);



// get the movie
AP4_Movie* movie = input_file->GetMovie();




if (movie != NULL) {
AP4_List<AP4_Track>& tracks = movie->GetTracks();
AP4_Debug("Found %d Tracks\n", tracks.ItemCount());
// get audio track


AP4_Track* video_track = movie->GetTrack(AP4_Track::TYPE_VIDEO);


if (video_track != NULL) {
// show info
AP4_Debug("Video Track:\n");
AP4_Debug(" duration: %ld ms\n", video_track->GetDurationMs());
AP4_Debug(" sample count: %ld\n", video_track->GetSampleCount());

AP4_TrakAtom* mp4_Video_Track = video_track->GetTrakAtom();
AP4_Debug(" mp4_Video_Track duration: %ld ms\n", mp4_Video_Track->GetDuration());
AP4_StsdAtom* mp4_Video_StsdAtom = (AP4_StsdAtom*)mp4_Video_Track->FindChild("mdia/minf/stbl/stsd");

AP4_AvccAtom* mp4_Video_AvccAtom = (AP4_AvccAtom*)mp4_Video_StsdAtom->FindChild("avc1/avcC");
AP4_Ordinal sindex = mp4_Video_AvccAtom->GetSequenceParameters().ItemCount();
AP4_Ordinal pindex = mp4_Video_AvccAtom->GetPictureParameters().ItemCount();


AP4_StssAtom *mp4_StssAtom = (AP4_StssAtom*)mp4_Video_Track->FindChild("mdia/minf/stbl/stss");


AP4_Sample sample;
AP4_DataBuffer data;
AP4_Ordinal index =1;
while (AP4_SUCCEEDED(video_track->ReadSample(index, sample, data))) {

if(mp4_StssAtom->IsSampleSync(index))
{
WriterAvccHeader(output);
output->Write(mp4_Video_AvccAtom->GetSequenceParameters()[0].GetData(),mp4_Video_AvccAtom->GetSequenceParameters()[0].GetDataSize());

WriterAvccHeader(output);
output->Write(mp4_Video_AvccAtom->GetPictureParameters()[0].GetData(),mp4_Video_AvccAtom->GetPictureParameters()[0].GetDataSize());

AP4_Debug(" [%d] sync sample writing %ld bytes of data...\n",
index, sample.GetSize());

}
WriterAvccHeader(output);
output->Write(data.GetData()+4, data.GetDataSize()-4);

AP4_Debug(" [%d] writing %ld bytes of data...\n",
index, sample.GetSize());

index++;
}
} else {
AP4_Debug("No Video track found\n");
}
} else {
AP4_Debug("No Movie in file\n");
}

delete input_file;
input->Release();

return 0;

}