📄 mpgplay.cpp
字号:
addref_buffer (&(BP->B[idx])); if (Flags & PTS_VALID_FLAG) { if (Flags & SCR_VALID_FLAG) { Scr = Scr * mpeg4TimeScale / 90000; if (Scr == 0) Scr = 1; } else if (videoFormat_mpeg12 == 0) { Scr = 0; } Flags = PTS_AVAILABLE_FLAG; if (videoFormat_mpeg12 == 0) { Pts = Pts * mpeg4TimeScale / 90000; Flags = CTS_AVAILABLE_FLAG; } DEBUGMSG (0, ("audio: [%d] scr=%d, pts=%d\n", (int)Length, (int)Scr, (int)Pts)); } else { DEBUGMSG (0, ("audio: [%d]\n", (int)Length)); Flags = 0; } ASSERT (Length); pMpegDecoder->WriteMpegAudio (pData, Length, &(BP->B[idx]), Flags, Scr, Pts); } return 0;}RMuint32 mpg_getDetectionBuffer (RMuint8 **pBuffer, RMuint32 *plength, void *context){ *pBuffer = (RMuint8 *)databuffers; return 0;}#include "bitstrm.h"RMint64 find_vop_time_increment_resolution (RMuint8 *p, RMint32 l){ BitStream *pbits; // search for the video_object_layer_start_code while (l > 3) { if ((p[0] == 0x00) && (p[1] == 0x00) && (p[2] == 0x01) && (p[3] >= 0x20) && (p[3] <= 0x2f)) { int err, marker_bit; DEBUGMSG (1, ("BitStream (%d)\n", (int)l-4)); err = 0; pbits = new BitStream (p+4, (long int)l-4, &err); if (pbits == 0) { DEBUGMSG (1, ("error creating bit parser object\n")); return 0; } ASSERT (err == 0); // video_object_layer_start_code found // parse it to find the vop_time_increment_resolution // the mpeg engine will use this as the timescale, so // we need this value to change the 90kHz mpeg program // stream time stamps to this scale DEBUGMSG (1, ("video_object_layer_start_code\n")); int video_object_layer_verid = -1; int random_accessible_vol = pbits->getbits (1, &err); ASSERT (err == 0); DEBUGMSG (1, (" random_accessible_vol: %d\n", random_accessible_vol)); int video_object_type_indication = pbits->getbits (8, &err); ASSERT (err == 0); DEBUGMSG (1, (" video_object_type_indication: %d\n", video_object_type_indication)); int is_object_layer_identifier = pbits->getbits (1, &err); ASSERT (err == 0); DEBUGMSG (1, (" is_object_layer_identifier: %d\n", is_object_layer_identifier)); if (is_object_layer_identifier) { video_object_layer_verid = pbits->getbits (4, &err); ASSERT (err == 0); DEBUGMSG (1, ("video_object_layer_verid: %d\n", video_object_layer_verid)); int video_object_priority = pbits->getbits (3, &err); ASSERT (err == 0); DEBUGMSG (1, ("video_object_priority: %d\n", video_object_priority)); }//// warning here! if (video_object_layer_verid == -1) { DEBUGMSG (1, ("WARNING: video_object_layer_verid was not specified: defaulting to 1\n")); video_object_layer_verid = 1; }//////////////// char *aspect_ratio_info_table[] = { "Forbidden", "1:1 (Square)", "12:11 (625-type for 4:3 picture)", "10:11 (525-type for 4:3 picture)", "16:11 (625-type stretched for 16:9 picture", "40:33 (525-type stretched for 16:9 picture", "Reserved", "Reserved", "Reserved", "Reserved", "Reserved", "Reserved", "Reserved", "Reserved", "Reserved", "Extended PAR" }; int aspect_ratio_info = pbits->getbits (4, &err); ASSERT (err == 0); DEBUGMSG (1, (" aspect ratio: %s\n", aspect_ratio_info_table[aspect_ratio_info])); if (aspect_ratio_info == 0xf) { int par_width = pbits->getbits (8, &err); ASSERT (err == 0); int par_height = pbits->getbits (8, &err); ASSERT (err == 0); DEBUGMSG (1, (" par_width = %d, par_height = %d\n", par_width, par_height)); } int vol_control_parameters = pbits->getbits (1, &err); ASSERT (err == 0); DEBUGMSG (1, (" vol_control_parameters: %d\n", vol_control_parameters)); if (vol_control_parameters) { int chroma_format = pbits->getbits (2, &err); ASSERT (err == 0); int low_delay = pbits->getbits (1, &err); ASSERT (err == 0); int vbv_parameters = pbits->getbits (1, &err); ASSERT (err == 0); if (vbv_parameters) { int first_half_bit_rate = pbits->getbits (15, &err); ASSERT (err == 0); marker_bit = pbits->getbits (1, &err); ASSERT (err == 0); ASSERT (marker_bit); int latter_half_bit_rate = pbits->getbits (15, &err); ASSERT (err == 0); marker_bit = pbits->getbits (1, &err); ASSERT (err == 0); ASSERT (marker_bit); int first_half_vbv_buffer_size = pbits->getbits (15, &err); ASSERT (err == 0); marker_bit = pbits->getbits (1, &err); ASSERT (marker_bit); int latter_half_vbv_buffer_size = pbits->getbits (3, &err); ASSERT (err == 0); int first_half_vbv_occupancy = pbits->getbits (11, &err); ASSERT (err == 0); marker_bit = pbits->getbits (1, &err); ASSERT (err == 0); ASSERT (marker_bit); int latter_half_vbv_occupancy = pbits->getbits (15, &err); ASSERT (err == 0); marker_bit = pbits->getbits (1, &err); ASSERT (err == 0); ASSERT (marker_bit); } } int video_object_layer_shape = pbits->getbits (2, &err); ASSERT (err == 0); char *video_object_layer_shape_table[] = { "rectangular", "binary", "binary only", "grayscale" }; DEBUGMSG (1, (" video_object_layer_shape = %s\n", video_object_layer_shape_table[video_object_layer_shape])); if ((video_object_layer_shape == 3) && (video_object_layer_verid != 1)) { ASSERT (video_object_layer_verid != -1); int video_object_layer_shape_extension = pbits->getbits (4, &err); ASSERT (err == 0); } marker_bit = pbits->getbits (1, &err); ASSERT (err == 0); DEBUGMSG (1, (" marker_bit: %d\n", marker_bit)); ASSERT (marker_bit); RMint64 vop_time_increment_resolution; vop_time_increment_resolution = pbits->getbits (16, &err); if (err) { DEBUGMSG (1, ("error reading vop_time_increment_resolution\n")); return 0; } ASSERT (err == 0); DEBUGMSG (1, (" vop_time_increment_resolution = %d\n", vop_time_increment_resolution)); delete pbits; return vop_time_increment_resolution; } p++; l--; } return 0;}int main (int argc, char *argv[]){ int ir_fd; if (argc < 2) { printf ("usage: mpgplay <filename> <ismpeg4>\n"); return -1; } open_input ();#ifdef USE_FATFS_LIB FATFS_ERROR err; FATFS_CALLBACK_TABLE callbacktable; ata_fd = open ("/dev/ata", O_RDWR | O_NONBLOCK); ASSERT (ata_fd != -1); if (ata_fd == -1) { printf ("error opening /dev/ata\n"); return -1; } callbacktable.Ata_SendCmd = fatfs_Ata_SendCmd; callbacktable.Ata_SendCmdRWS = fatfs_Ata_SendCmdRWS; callbacktable.malloc = fatfs_malloc; callbacktable.mfree = fatfs_free; err = fatfs_mount (0, &callbacktable, 1); if (err != FATFS_ERROR_NO_ERROR) { printf ("error mounting filesystem.\n"); close (ata_fd); return -1; }#endif pMpegDecoder = (MpegDecoder *) new MpegDecoder; ASSERT (pMpegDecoder); pMpegDecoder->Init (); // ntsc pMpegDecoder->SetupDisplay (1); // set mpeg-1/2 OR mpeg-4 video content MPEGVIDEO_PARAMETERS videoparams; videoFormat_mpeg12 = !atoi (argv[2]); if (videoFormat_mpeg12) { // mpeg-1 or mpeg-2 printf ("assuming mpeg1 or mpeg2 video\n"); videoparams.isMPEG4 = 0; videoparams.vopTimeIncrRes = 0; videoparams.videoTimeScale = 0; videoparams.audioTimeScale = 0; videoparams.fixedVOPRate = 0; videoparams.vopTimeIncr = 0; pMpegDecoder->SetMpegVideoParameters (&videoparams); } else { printf ("assuming mpeg4 video\n"); printf ("searching for the mpeg4TimeScale in the file ...\n"); RMuint32 f = mpg_fopen (argv[1], 0); if (f) { RMint32 n; n = (RMint32)mpg_fread (f, databuffers, 1024 * 64, 0); mpeg4TimeScale = find_vop_time_increment_resolution ((RMuint8 *)databuffers, n); if (mpeg4TimeScale == 0) { printf ("WARNING: assuming mpeg4TimeScale = 90000\n"); mpeg4TimeScale = 90000; } mpg_fclose (f, 0); } videoparams.isMPEG4 = 1; videoparams.vopTimeIncrRes = mpeg4TimeScale; videoparams.videoTimeScale = mpeg4TimeScale; videoparams.audioTimeScale = mpeg4TimeScale; videoparams.fixedVOPRate = 0; videoparams.vopTimeIncr = 0; pMpegDecoder->SetMpegVideoParameters (&videoparams); } init_buffer_pool (&BPmpg, mpg_buffer, BUFFERSIZE, NBUFFERS); MPG_CALLBACK_TABLE callback; MPEGDemux *pDemux = (MPEGDemux *) new MPEGDemux; pDemux->Init (); callback.context = 0; callback.fopen = mpg_fopen; callback.fread = mpg_fread; callback.fseek = mpg_fseek; callback.fclose = mpg_fclose; callback.addref = mpg_addref; callback.release = mpg_release; callback.info = mpg_info; callback.putpayload = mpg_putpayload; callback.getMPG = mpg_getMPG; callback.getDetectionBuffer = mpg_getDetectionBuffer; pDemux->InitCallbackTable (&callback); ir_fd = open ("/dev/ir", O_RDWR | O_NONBLOCK); if (pDemux->DecodeFile (argv[1]) == MPG_DEMUX_ERROR_NO_ERROR) { iframe_only = 0; pMpegDecoder->Play (); RMuint32 t0, t1; RMint64 currentTime = -1; t0 = 0; while (pDemux->Schedule () != MPG_DEMUX_ERROR_FILE_DONE) { t1 = gettime_ms (); if ((t1 - t0) > 500) { RMint64 t; RMint8 text[64]; pMpegDecoder->GetSTC (&t, 1); if (t != currentTime) { currentTime = t; RMint64 hours = currentTime / 3600; RMint64 minutes = (currentTime - hours * 3600) / 60; RMint64 seconds = currentTime - hours*3600 - minutes*60; sprintf (text, "%02d:%02d:%02d", (RMint32)hours, (RMint32)minutes, (RMint32)seconds); pMpegDecoder->RenderText (text, 0x0000ff, 32, 240-26, 260-32, 26); } t0 = t1; } RMuint32 input = 0;#ifdef SUPPORT_IR if (ir_fd != -1) { ioctl (ir_fd, IR_IOCTL_READ_KEY, &input); } else#endif { char c; c = 0; get_input_key (&c); if (c == 'p') input = PLAY_SCANCODE; else if (c == 'f') input = FF_SCANCODE; else if (c == 'r') input = FR_SCANCODE; else if ((c == 'x') || (c == 'q')) goto hard_exit; } switch (input) { case PLAY_SCANCODE: DEBUGMSG (1, ("PLAY\n")); if (iframe_only) { pDemux->SendIFramesOnly (0); pMpegDecoder->PlayIFrame (0); iframe_only = 0; } break; case FR_SCANCODE: DEBUGMSG (1, ("FAST REVERSE\n")); if (iframe_only == 0) { // enable i frame only mode // see comments below iframe_only = -1; pDemux->SendIFramesOnly (-128 * 1024 * 8); pMpegDecoder->PlayIFrame (-256 * 4); } break; case FF_SCANCODE: DEBUGMSG (1, ("FAST FORWARD\n")); if (iframe_only == 0) { // enable i frame only mode iframe_only = 1; // the input parameter here is a bit tricky to calculate // it should be big enough so that the data can be read // fast enough from the device, but it should not be so large // so that too much data is skipped. // basically: // for slower speeds, this value should be smaller. // for faster speeds, this value should be larger. // for larger mpeg bitrates, this value should be larger. // for smaller bitrates, this value should be smaller. // // you must fine tune this number to meet your needs // the best number for this parameter is to be just slightly // smaller than the distance between 2 I frames, which is // usually a GOP (group of pictures). pDemux->SendIFramesOnly (128 * 1024 * 8); // nominal = 256 // 1024 = 4x // 0 = back to normal // -'ve = backwards // +'ve = forwards pMpegDecoder->PlayIFrame (256 * 4); } break; } } // wait for last pts to pass while (1) { t1 = gettime_ms (); if ((t1 - t0) > 500) { RMint64 t, t90000; RMint8 text[64]; pMpegDecoder->GetSTC (&t, 1); pMpegDecoder->GetSTC (&t90000, 90000); if (t != currentTime) { currentTime = t; RMint64 hours = currentTime / 3600; RMint64 minutes = (currentTime - hours * 3600) / 60; RMint64 seconds = currentTime - hours*3600 - minutes*60; sprintf (text, "%02d:%02d:%02d", (RMint32)hours, (RMint32)minutes, (RMint32)seconds); pMpegDecoder->RenderText (text, 0x0000ff, 32, 240-26, 260-32, 26); DEBUGMSG (1, ("scr: %d\n", (RMint32)t90000)); DEBUGMSG (1, ("t90000: %d, lastPTS: %d\n", (RMint32)t90000, (RMint32)lastPTS)); } if (iframe_only < 0) { if ((RMint32)t90000 < (RMint32)lastPTS) break; } else { if ((RMint32)t90000 > (RMint32)lastPTS) break; } } }hard_exit: sleep (1); if (ir_fd != -1) close (ir_fd); } delete pDemux; pMpegDecoder->Stop (); pMpegDecoder->Exit (); delete pMpegDecoder; deinit_buffer_pool (&BPmpg);#ifdef USE_FATFS_LIB fatfs_umount (0);#endif close_input (); return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -