MPEG2 Audio and Video Splitter

I am using an Altera FPGA to split video and audio data from an *.mpg file. I receive mpg data and send to a IP MPEG2 Decoder Core purchased from Amphion Semiconductors. I have attempted to code a data splitter but have plenty of questions with the demultiplexing of the data.

The below describes the code at higher level:

if (prefix_code_recognized) // received 24'h000001 start_code

Reply to
amitpatel130
Loading thread data ...

What is the format of your *.mpg file? It is almost certainly either a mpeg2 transport stream or a packetized elementary stream. Either way, you will find start codes inside, but you will be looking "inside" the TS or PES packets and your output will be a hash.

A TS will start with 0x47 (and repeat every 188 bytes). I forget if there's anything special about a PES, but knowing it exists is half the battle. Either one will have enough information to allow you to split the file at a higher level than the individual start codes.

BTW, are you the Amit Patel I know?

--
Ben Jackson AD7GD

http://www.ben.com/
Reply to
Ben Jackson

Hello Ben,

Thank you for your response. I believe the data is PES, because the stream starts with a start_code of 32'h000001BA. I am using an IP MPEG2 Video Decoder in my design, and I need to split the mpeg2 video and audio data. I am doing so as shown above, but am still uncertain if this is the proper way to transmit the data. Do I have to go by the packet information and count my data? Below is a C++ description I am following. Let me know what you think. Thanks:

#include #include #include "MpegStream.h"

void MpegWrite(char* fname, HANDLE hFile, LPBYTE base, DWORD len, LPDWORD count, BYTE c) { base[*count] = c; if (++*count >= len) { DWORD dwBytesWritten; if (!WriteFile(hFile, base, len, &dwBytesWritten, NULL)) { LPVOID errmsg; FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, 0, GetLastError(), 0, (LPSTR)&errmsg, 0, NULL); fprintf(stderr, "WriteFile %s failure (%d) %s\n", fname, GetLastError(), errmsg); LocalFree(errmsg); ExitProcess(1); } *count = 0; } }

int main(int argc, char* argv[]) { LPVOID errmsg; BYTE cMpegBuf[1024]; BYTE cVideoBuf[1024]; BYTE cAudioBuf[1024]; LPBYTE lpMpeg; DWORD dwMpeg; DWORD dwVideo; DWORD dwAudio; DWORD dwVES; DWORD dwAES;

// check command line arguments if (argc != 4) { fputs("Usage: MpegSplitter \n", stderr); ExitProcess(1); }

// open input MPG file HANDLE hMpeg = CreateFile(argv[1], GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL); if (hMpeg == (HANDLE)INVALID_HANDLE_VALUE) { FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, 0, GetLastError(), 0, (LPSTR)&errmsg, 0, NULL); fprintf(stderr, "CreateFile %s failure (%d) %s\n", argv[1], GetLastError(), errmsg); LocalFree(errmsg); ExitProcess(1); }

// create output video file HANDLE hVideo = CreateFile(argv[2], GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL); if (hVideo == (HANDLE)INVALID_HANDLE_VALUE) { FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, 0, GetLastError(), 0, (LPSTR)&errmsg, 0, NULL); fprintf(stderr, "CreateFile %s failure (%d) %s\n", argv[2], GetLastError(), errmsg); LocalFree(errmsg); ExitProcess(1); }

// open input MPG file HANDLE hAudio = CreateFile(argv[3], GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL); if (hAudio == (HANDLE)INVALID_HANDLE_VALUE) { FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, 0, GetLastError(), 0, (LPSTR)&errmsg, 0, NULL); fprintf(stderr, "CreateFile %s failure (%d) %s\n", argv[3], GetLastError(), errmsg); LocalFree(errmsg); ExitProcess(1); }

// split mpeg into video and audio lpMpeg = cMpegBuf; dwMpeg = 0; dwVideo = 0; dwAudio = 0; dwVES = 0; dwAES = 0;

int state = 1; while (1) { // if need mpeg data if (dwMpeg == 0) { if (!ReadFile(hMpeg, cMpegBuf, sizeof(cMpegBuf), &dwMpeg, NULL)) { FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, 0, GetLastError(), 0, (LPSTR)&errmsg, 0, NULL); fprintf(stderr, "ReadFile %s failure (%d) %s\n", argv[1], GetLastError(), errmsg); LocalFree(errmsg); ExitProcess(1); } if (dwMpeg == 0) break; lpMpeg = cMpegBuf; }

// process mpeg data switch (state) { case 1 : // look for first byte of start code if (*lpMpeg == 0) state = 2; else { MpegWrite(argv[2], hVideo, cVideoBuf, sizeof(cVideoBuf), &dwVideo,

*lpMpeg); MpegWrite(argv[3], hAudio, cAudioBuf, sizeof(cAudioBuf), &dwAudio, *lpMpeg); } break;

case 2 : // look for second byte of start code if (*lpMpeg == 0) state = 3; else { state = 1;

MpegWrite(argv[2], hVideo, cVideoBuf, sizeof(cVideoBuf), &dwVideo,

0); MpegWrite(argv[2], hVideo, cVideoBuf, sizeof(cVideoBuf), &dwVideo, *lpMpeg);

MpegWrite(argv[3], hAudio, cAudioBuf, sizeof(cAudioBuf), &dwAudio,

0); MpegWrite(argv[3], hAudio, cAudioBuf, sizeof(cAudioBuf), &dwAudio, *lpMpeg); } break;

case 3 : // look for third byte of start code if (*lpMpeg == 1) state = 4; else if (*lpMpeg != 0) { state = 1;

MpegWrite(argv[2], hVideo, cVideoBuf, sizeof(cVideoBuf), &dwVideo,

0); MpegWrite(argv[2], hVideo, cVideoBuf, sizeof(cVideoBuf), &dwVideo, 0); MpegWrite(argv[2], hVideo, cVideoBuf, sizeof(cVideoBuf), &dwVideo, *lpMpeg);

MpegWrite(argv[3], hAudio, cAudioBuf, sizeof(cAudioBuf), &dwAudio,

0); MpegWrite(argv[3], hAudio, cAudioBuf, sizeof(cAudioBuf), &dwAudio, 0); MpegWrite(argv[3], hAudio, cAudioBuf, sizeof(cAudioBuf), &dwAudio, *lpMpeg); } break;

case 4 : // have start code. process start code // if start of video elementary stream if (*lpMpeg >= VIDEO_ELEMENTARY_STREAM && *lpMpeg < VIDEO_ELEMENTARY_STREAM + 0x10) // VIDEO_ELEMENTARY_STREAM == 0xE0 { state = 5;

MpegWrite(argv[2], hVideo, cVideoBuf, sizeof(cVideoBuf), &dwVideo,

0); MpegWrite(argv[2], hVideo, cVideoBuf, sizeof(cVideoBuf), &dwVideo, 0); MpegWrite(argv[2], hVideo, cVideoBuf, sizeof(cVideoBuf), &dwVideo, 1); MpegWrite(argv[2], hVideo, cVideoBuf, sizeof(cVideoBuf), &dwVideo, *lpMpeg); } // if start of audio elementary stream else if (*lpMpeg >= AUDIO_ELEMENTARY_STREAM && *lpMpeg < AUDIO_ELEMENTARY_STREAM + 0x20) // AUDIO_ELEMENTARY_STREAM == 0xC0 { state = 8;

MpegWrite(argv[3], hAudio, cAudioBuf, sizeof(cAudioBuf), &dwAudio,

0); MpegWrite(argv[3], hAudio, cAudioBuf, sizeof(cAudioBuf), &dwAudio, 0); MpegWrite(argv[3], hAudio, cAudioBuf, sizeof(cAudioBuf), &dwAudio, 1); MpegWrite(argv[3], hAudio, cAudioBuf, sizeof(cAudioBuf), &dwAudio, *lpMpeg); } // if none of the above else { state = 1;

MpegWrite(argv[2], hVideo, cVideoBuf, sizeof(cVideoBuf), &dwVideo,

0); MpegWrite(argv[2], hVideo, cVideoBuf, sizeof(cVideoBuf), &dwVideo, 0); MpegWrite(argv[2], hVideo, cVideoBuf, sizeof(cVideoBuf), &dwVideo, 1); MpegWrite(argv[2], hVideo, cVideoBuf, sizeof(cVideoBuf), &dwVideo, *lpMpeg);

MpegWrite(argv[3], hAudio, cAudioBuf, sizeof(cAudioBuf), &dwAudio,

0); MpegWrite(argv[3], hAudio, cAudioBuf, sizeof(cAudioBuf), &dwAudio, 0); MpegWrite(argv[3], hAudio, cAudioBuf, sizeof(cAudioBuf), &dwAudio, 1); MpegWrite(argv[3], hAudio, cAudioBuf, sizeof(cAudioBuf), &dwAudio, *lpMpeg); } break;

case 5 : // here for MSB of VES byte count dwVES = *lpMpeg

Reply to
amitpatel130

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.