winlin

remove the flv muxer

... ... @@ -1958,152 +1958,6 @@ public:
}
};
class FlvMuxer
{
public:
int fd;
const char* file;
bool audio_sequence_header_writen;
FlvMuxer()
{
file = NULL;
fd = 0;
audio_sequence_header_writen = false;
}
virtual ~FlvMuxer()
{
if (fd > 0) {
close(fd);
}
}
int open(const char* _file)
{
file = _file;
if ((fd = ::open(file, O_CREAT|O_WRONLY|O_TRUNC,
S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH)) < 0
) {
return -1;
}
char header[] = {
0x46, 0x4c, 0x56, // FLV
0x01, // version: 01
0x04, // 0x05:audio+video, 0x01:video, 0x04:audio
0x00, 0x00, 0x00, 0x09, // offset: always 0x09
0x00, 0x00, 0x00, 0x00 // previous tag 0: always 0
};
if (write(fd, header, sizeof(header)) != sizeof(header)) {
return -1;
}
return 0;
}
/**
* @param size, if 0 for sequence header.
* @param sound_rate, Sampling rate. The following values are defined:
* 0 = 5.5 kHz
* 1 = 11 kHz
* 2 = 22 kHz
* 3 = 44 kHz
* @param sound_type, Mono or stereo sound
* 0 = Mono sound
* 1 = Stereo sound
*/
int write_audio(char* data, int size, u_int32_t timestamp, int sound_rate, int sound_type)
{
if (size > 0 && !audio_sequence_header_writen) {
audio_sequence_header_writen = true;
if (write_audio(NULL, 0, 0, sound_rate, sound_type) != 0) {
return -1;
}
}
char tag_header[11];
char sequence_header[2]; // aac only
int data_size = size + sizeof(sequence_header);
int tag_size = data_size + sizeof(tag_header);
////////////////////////////////////
// 11bytes tag header.
////////////////////////////////////
// TagType
char* p = tag_header;
*p++ = 0x08; // audio
// DataSize
char* pp = (char*)&data_size;
*p++ = pp[2];
*p++ = pp[1];
*p++ = pp[0];
// Timestamp
pp = (char*)&timestamp;
*p++ = pp[2];
*p++ = pp[1];
*p++ = pp[0];
// TimestampExtended
*p++ = pp[3];
//StreamID
*p++ = 0;
*p++ = 0;
*p++ = 0;
////////////////////////////////////
// 2bytes codec header for aac
////////////////////////////////////
// SoundFormat
sequence_header[0] = 0xa0; // aac
sequence_header[0] |= (sound_rate << 2) & 0x0c;
sequence_header[0] |= 0x02; // Compressed formats always decode to 16 bits internally.
sequence_header[0] |= sound_type & 0x01;
// AACPacketType
if (size == 0) {
sequence_header[1] = 0x00;
} else {
sequence_header[1] = 0x01;
}
////////////////////////////////////
// 4bytes tag size
////////////////////////////////////
char tag_size_bytes[4];
p = tag_size_bytes;
pp = (char*)&tag_size;
*p++ = pp[4];
*p++ = pp[2];
*p++ = pp[1];
*p++ = pp[0];
// write
if (write(fd, tag_header, sizeof(tag_header)) != sizeof(tag_header)) {
return -1;
}
if (write(fd, sequence_header, sizeof(sequence_header)) != sizeof(sequence_header)) {
return -1;
}
if (size > 0 && write(fd, data, size) != size) {
return -1;
}
if (write(fd, tag_size_bytes, sizeof(tag_size_bytes)) != sizeof(tag_size_bytes)) {
return -1;
}
return 0;
}
int write_video(char* data, int size)
{
return 0;
}
};
class AacMuxer
{
public:
... ... @@ -2150,7 +2004,7 @@ public:
}
};
int consume(TSMessage* msg, FlvMuxer* flv, AacMuxer* aac_muxer)
int consume(TSMessage* msg, AacMuxer* aac_muxer)
{
int ret = 0;
... ... @@ -2176,35 +2030,7 @@ int consume(TSMessage* msg, FlvMuxer* flv, AacMuxer* aac_muxer)
}
trace("ts+aac audio raw data parsed, size: %d, 0x%02x 0x%02x 0x%02x 0x%02x",
aac.size, aac.at(0), aac.at(1), aac.at(2), aac.at(3));
int sound_rate = 0;
if (aac.sampling_frequency_index == TSAacSampleFrequency22050) {
sound_rate = 0x02;
} else if(aac.sampling_frequency_index == TSAacSampleFrequency44100) {
sound_rate = 0x03;
} else {
// 0 = 5.5 kHz
// 1 = 11 kHz
// others.
trace("ts+aac flv donot support sample-rate: %d", aac.sampling_frequency_index);
return -1;
}
int sound_type = 0;
if (aac.channel_configuration == 1) {
// 0 = Mono sound
sound_type = 0;
} else if (aac.channel_configuration == 2) {
// 1 = Stereo sound
sound_type = 1;
} else {
trace("ts+aac flv donot support channel: %d", aac.channel_configuration);
return -1;
}
if (flv && (ret = flv->write_audio((char*)aac.raw_data, aac.size, msg->pts, sound_rate, sound_type)) != 0) {
return ret;
}
// TODO: process audio.
}
} else {
// parse H264 video.
... ... @@ -2222,21 +2048,19 @@ int consume(TSMessage* msg, FlvMuxer* flv, AacMuxer* aac_muxer)
return ret;
}
int main(int /*argc*/, char** /*argv*/)
int main(int argc, char** argv)
{
const char* file = "livestream-1347.ts";
const char* output_flv_file = "livestream.flv";
const char* output_aac_file = "livestream.aac";
const char* output_aac_file = "output.aac";
if (argc > 2) {
file = argv[1];
output_aac_file = argv[2];
}
int fd = open(file, O_RDONLY);
FlvMuxer flv;
AacMuxer aac_muxer;
int ret = 0;
if ((ret = flv.open(output_flv_file)) != 0) {
trace("flv+open open flv file failed.");
return ret;
}
if ((ret = aac_muxer.open(output_aac_file)) != 0) {
trace("aac_muxer+open open flv file failed.");
return ret;
... ... @@ -2280,7 +2104,7 @@ int main(int /*argc*/, char** /*argv*/)
continue;
}
if ((ret = consume(msg, &flv, &aac_muxer)) != 0) {
if ((ret = consume(msg, &aac_muxer)) != 0) {
trace("demuxer+consume parse and consume message failed. ret=%d", ret);
break;
}
... ...