You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
tdemultimedia/mpeglib/lib/splay/mpegAudioFrame.cpp

201 lines
4.9 KiB

/*
converts raw mpeg audio stream data into mpeg I encoded audio frames/packets
Copyright (C) 2001 Martin Vogt
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU Library General Public License as published by
the Free Software Foundation.
For more information look at the file COPYRIGHT in this package
*/
#include "mpegAudioFrame.h"
#define MPEGAUDIOFRAMESIZE 4096
#define FRAME_SYNC 0
#define FRAME_CHECK_HEADER_1 1
#define FRAME_CHECK_HEADER_2 2
#include <iostream>
using namespace std;
MpegAudioFrame::MpegAudioFrame():Framer(MPEGAUDIOFRAMESIZE) {
mpegAudioHeader=new MpegAudioHeader();
}
MpegAudioFrame::~MpegAudioFrame() {
delete mpegAudioHeader;
}
void MpegAudioFrame::unsync(RawDataBuffer* store,int ) {
// invalidate header in buffer
unsigned char* start=store->ptr();
start[0]=0x0;
start[1]=0x0;
store->setpos(0);
find_frame_state=FRAME_SYNC;
framesize=0;
}
/**
here we parse byte by byte the raw input, first
we search for the magic bytes: 0xfffx, then
we read the remaining 2 bytes for the header,
check if they are "wrong" in a mpeg I audio special way.
If everything is fine, we continue with the next state.
Note: we can be sure here, that the "store" can at least
store 4 bytes.
*/
int MpegAudioFrame::find_frame(RawDataBuffer* input_buffer,
RawDataBuffer* store_buffer) {
unsigned char* store=store_buffer->current();
int back=false;
if (find_frame_state == FRAME_SYNC) {
if (store_buffer->pos() != 0) {
cout << "store buffer not at beginning MpegAudioFrame::find_frame"<<endl;
cout << "current state requires this"<<endl;
exit(0);
}
}
while(input_buffer->eof()==false) {
// search for sync bytes
unsigned char* input=input_buffer->current();
if (find_frame_state == FRAME_SYNC) {
while(input_buffer->eof() == false) {
input=input_buffer->current();
// shift
store[0]=store[1];
store[1]=input[0];
input_buffer->inc();
if (store[0] != 0xff) {
continue;
}
// upper 4 bit are syncword, except bit one
// which is layer 2.5 indicator.
if ( (store[1] & 0xe0) != 0xe0) {
continue;
}
// found header, now check if other info is ok, too.
store_buffer->setpos(2);
find_frame_state=FRAME_CHECK_HEADER_1;
break;
}
// back to "main loop"
continue;
}
// ok, try to read two other bytes and then validate the header
if (find_frame_state == FRAME_CHECK_HEADER_1) {
store[2]=input[0];
input_buffer->inc();
find_frame_state=FRAME_CHECK_HEADER_2;
// back to main loop
continue;
}
if (find_frame_state == FRAME_CHECK_HEADER_2) {
store[3]=input[0];
input_buffer->inc();
}
// ok, read 4 header bytes. Now check the validity of the
// header.
int lHeaderOk;
lHeaderOk=mpegAudioHeader->parseHeader(store);
if (lHeaderOk == false) {
find_frame_state=FRAME_SYNC;
store_buffer->setpos(0);
// go back to "sync for frame"
continue;
}
framesize=mpegAudioHeader->getFramesize();
// if framesize > max mepg framsize its an error
if (framesize+4 >= store_buffer->size()) {
find_frame_state=FRAME_SYNC;
store_buffer->setpos(0);
// go back to "sync for frame"
continue;
}
// don't allow stupid framesizes:
if (framesize <= 4) {
find_frame_state=FRAME_SYNC;
store_buffer->setpos(0);
continue;
}
// yup! found valid header. forward states
store_buffer->setpos(4);
back=true;
break;
}
return back;
}
/**
here we read data until len=framesize.
Then we go to the HAS_FRAME state.
*/
int MpegAudioFrame::read_frame(RawDataBuffer* input_buffer,
RawDataBuffer* store_buffer) {
unsigned char* store=store_buffer->current();
while(input_buffer->eof()==false) {
int has=store_buffer->pos();
int need=framesize-has;
if(need == 0) {
// yup! frame fully read. forward states.
// go to end state for main_state.
return true;
}
// try to do a memcpy for speed.
int can=input_buffer->untilend();
if(can > need) {
can=need;
}
unsigned char* input=input_buffer->current();
memcpy(store,input,can);
store_buffer->inc(can);
input_buffer->inc(can);
}
int need=framesize-store_buffer->pos();
if(need == 0) {
// yup! frame fully read. forward states.
// go to end state for main_state.
return true;
}
return false;
}
void MpegAudioFrame::printPrivateStates() {
cout << "MpegAudioFrame::printPrivateStates"<<endl;
switch(find_frame_state) {
case FRAME_SYNC:
cout << "frame_state: FRAME_SYNC"<<endl;
break;
case FRAME_CHECK_HEADER_1:
cout << "frame_state: FRAME_CHECK_HEADER_1"<<endl;
break;
case FRAME_CHECK_HEADER_2:
cout << "frame_state: FRAME_CHECK_HEADER_2"<<endl;
break;
default:
cout << "unknown illegal frame_state:"<<find_frame_state<<endl;
}
}