📄 play_avi_push.c
字号:
/* * * Copyright (c) Sigma Designs, Inc. 2002. All rights reserved. * *//** @file dcc_demo.c @brief sample application to access the Mambo chip and test DMA transfers @author Julien Soulier @ingroup dccsamplecode*/#include <stdio.h>#include <stdlib.h>#include <string.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <unistd.h>#include <sys/time.h>#define ALLOW_OS_CODE 1#include "../dcc/include/dcc.h"#include "../rmlibhttp/include/rmlibhttp.h"#include "common.h"#include "rminputstream.h"#include "../rmavicore/include/rmavipushapi.h"/* ################## Begin DTCP code ################### */#if (EM86XX_CHIP == EM86XX_CHIPID_TANGO15)#include "../rmdtcp/include/dtcp_session.h"#else#include "../rmdtcpapi/include/dtcp_session.h"#endif/* ############### End DTCP code ####################### */#define COMMON_TIMEOUT_US (TIMEOUT_10MS)#define SENDDATA_TIMEOUT_US (TIMEOUT_10MS)#define DMA_BUFFER_SIZE_LOG2 16#define DMA_BUFFER_COUNT 16 // 16*32kB = 512KB#define VIDEO_DMA_BUFFER_SIZE_LOG2 15 // 32kB#define VIDEO_DMA_BUFFER_COUNT 16 // 16*32kB = 512KB#define AUDIO_DMA_BUFFER_SIZE_LOG2 16 // 64kB#define AUDIO_DMA_BUFFER_COUNT 2 // 2*64kB = 128KB#define VIDEO_XFER_FIFO_COUNT (VIDEO_DMA_BUFFER_COUNT * (1<<VIDEO_DMA_BUFFER_SIZE_LOG2) / 2048) // average video packet size = 2k#define AUDIO_XFER_FIFO_COUNT (AUDIO_DMA_BUFFER_COUNT * (1<<AUDIO_DMA_BUFFER_SIZE_LOG2) / 2048) // average audio packet size = 2k#define AUDIO_BASE 90000#define VIDEO_FIFO_SIZE (10*512*1024) // ~= 10sec at 500kB/sec.#define AUDIO_FIFO_SIZE (10*64*1024) // ~= 10sec at 64kB/sec.#define KEYFLAGS (SET_KEY_DISPLAY | SET_KEY_PLAYBACK | SET_KEY_AUDIO | SET_KEY_SPI)#if 0#define AVIDBG ENABLE#else#define AVIDBG DISABLE#endif#if 0#define VC1_STARTCODE_DBG ENABLE#else#define VC1_STARTCODE_DBG DISABLE#endif#define MAX_AUDIO_TRACK_COUNT 8#define SENDDBG DISABLE#define RM_DEVICES_STC 0x1#define RM_DEVICES_VIDEO 0x2#define RM_DEVICES_AUDIO 0x4static struct RM_PSM_Actions actions;static struct playback_cmdline *play_opt;static struct video_cmdline *video_opt;struct display_cmdline *disp_opt;static struct audio_cmdline *audio_opt;static RMuint32 audioInstances;enum goto_state { LABEL_ERROR = 1, LABEL_NONE, LABEL_QUIT, LABEL_STOP, LABEL_STOP_SEEK_ZERO};struct avi_interleaved_context{ RMuint32 audio_chunks; RMuint32 video_chunks; RMbool interleaved;};struct avi_audio_context { RMint32 streamID; RMuint32 audioByteCounter; RMuint32 audioFrameCounter; RMAviAudioFormat audioFormat; RMbool skipBogusAudioChunk; RMuint64 audioPTS; RMuint64 real_audio_pts; // this is the PTS we send to the decoder, it is scaled by audio_base/audio_time_scale RMbool audio_VBR; RMuint32 audioTimeScale; RMuint32 audio_base; RMuint32 audio_sample_rate; enum AudioDecoder_Codec_type Codec; RMuint32 subCodec;}; struct avi_context { struct RUA *pRUA; struct RUABufferPool *pDMA; struct dcc_context *dcc_info; struct RM_PSM_Context *PSMcontext; struct avi_audio_context audio_info[MAX_AUDIO_TRACK_COUNT]; RMuint32 audio_stream_count; RMbool switching_audio; RMfile avi_file; RMaviPushHandle pAvi; RMuint32 videoFrameCounter; RMuint32 vopTimeIncrement; RMuint32 vopTimeIncrementResolution; RMAviVideoFormat videoFormat; RMuint32 currentAudioStream; RMint32 currentAudioIndex; RMuint64 videoPTS; RMbool sendVideoData; RMbool sendAudioData; RMbool need_audio_au; RMbool quitCallback; enum goto_state label; RMbool iframe; RMbool video_end; RMuint32 read_size;#ifdef _DEBUG RMint64 max_diff; RMint64 min_diff;#endif RMuint32 prebuf_level; RMuint32 movi_index; RMbool monitorFIFOs; RMbool setVOP; struct RMFileStreamInfo streamInfo; RMbool firstPTS; RMbool dontSendMPEG4pts; void **dmabuffer_array; RMuint32 dmabuffer_index; // for VC1 RMuint8 *seqHeader; RMuint32 seqHeaderSize; RMbool addSeqHeader; RMbool addEntryHeader; RMbool addFrameHeader; RMuint8 *entryHeader; RMuint32 entryHeaderSize; RMbool isVC1; RMbool getStartCodeBuffer; RMuint8 *startCodeBuffer; RMuint32 startCodeBufferSize; RMuint32 startCodeBufferLeft; RMbool frameIsIFrame;};#define GET_DATA_FIFO_INFO(pRUA, ModuleId) \ { \ struct DataFIFOInfo DataFIFOInfo; \ RMreal fullness; \ RUAGetProperty(pRUA, ModuleId, RMGenericPropertyID_DataFIFOInfo, &DataFIFOInfo, sizeof(DataFIFOInfo)); \ fullness = (RMreal)((100./DataFIFOInfo.Size)*DataFIFOInfo.Readable); \ fprintf(stderr, "Data %lx: st=%08lx sz=%ld wr=%ld rd=%ld --> f : %.02f\n", ModuleId, DataFIFOInfo.StartAddress, \ DataFIFOInfo.Size, DataFIFOInfo.Writable, DataFIFOInfo.Readable, fullness); \ } \#define GET_XFER_FIFO_INFO(pRUA, ModuleId) \ { \ struct XferFIFOInfo_type XferFIFOInfo; \ RMreal fullness; \ RUAGetProperty(pRUA, ModuleId, RMGenericPropertyID_XferFIFOInfo, &XferFIFOInfo, sizeof(XferFIFOInfo)); \ fullness = (RMreal)((100./XferFIFOInfo.Size)*XferFIFOInfo.Readable); \ fprintf(stderr, "XFER %lx: st=%08lx sz=%ld wr=%ld rd=%ld er=%lx --> f : %.02f \n", ModuleId, XferFIFOInfo.StartAddress, \ XferFIFOInfo.Size, XferFIFOInfo.Writable, XferFIFOInfo.Readable, XferFIFOInfo.Erasable, fullness); \ }#define MONITOR_FIFO_INTERVAL_US 250000static void monitorFIFO(struct avi_context *context, RMbool alwaysShow){ struct timeval now; static struct timeval last; static int first = 1; int elapsed; RMuint64 ptime; struct dcc_context *dcc_info = context->dcc_info; gettimeofday(&now, NULL); elapsed = (now.tv_sec - last.tv_sec) * 1000000; elapsed += (now.tv_usec - last.tv_usec); if (elapsed > MONITOR_FIFO_INTERVAL_US || first || alwaysShow){ DCCSTCGetTime(dcc_info->pStcSource, &ptime, 90000); fprintf(stderr, " \n***************************** \n"); fprintf(stderr, "STC = %llu (%llu secs) \n", ptime, (ptime/90000)); /* sample code to get fifo info */ if (dcc_info->pVideoSource) { fprintf(stderr, "Video :\n"); GET_DATA_FIFO_INFO(dcc_info->pRUA, dcc_info->video_decoder); GET_XFER_FIFO_INFO(dcc_info->pRUA, dcc_info->video_decoder); } if (dcc_info->pMultipleAudioSource) { struct DCCAudioSourceHandle audioHandle; RMuint32 i; for (i = 0; i < audioInstances; i++) { fprintf(stderr, "Audio[%lu] :\n", i); DCCMultipleAudioSourceGetSingleDecoderHandleForInstance(dcc_info->pMultipleAudioSource, i, &audioHandle); GET_DATA_FIFO_INFO(dcc_info->pRUA, audioHandle.moduleID); GET_XFER_FIFO_INFO(dcc_info->pRUA, audioHandle.moduleID); } } fprintf(stderr, "***************************** \n"); gettimeofday(&last, NULL); first = 0; fflush(stderr); } return;}struct priv_cmdline { RMuint32 audio_track; // audio track to play RMuint32 internal_file_open; // should we open the file internally RMbool play_noninterleaved_avi; // force playback of non interleaved files RMbool monitorFIFOs;};RMstatus switch_audio(struct avi_context *avi_info);static struct priv_cmdline priv_opt;static RMuint64 round_int_div(RMuint64 numerator, RMuint32 divisor) { RMuint64 temp; temp = numerator / divisor; if ((numerator % divisor) * 2 > divisor) temp++; return temp;}static RMstatus init_private_options(struct priv_cmdline *options){ options->audio_track = 0; options->internal_file_open = 0; options->play_noninterleaved_avi = FALSE; options->monitorFIFOs = FALSE; return RM_OK;}#ifndef WITH_MONOstatic RMstatus parse_private_cmdline(int argc, char **argv, int *index, struct priv_cmdline *options){ RMstatus err = RM_PENDING; int i = *index; if (! strcmp(argv[i], "-at")) { printf("found AT\n"); if (argc > i+1) { options->audio_track = strtol(argv[i+1], NULL, 10); printf("found AT: %lu\n", options->audio_track); i+=2; err = RM_OK; } else err = RM_ERROR; } else if ( ! strcmp(argv[i], "-force_ni_avi")) { options->play_noninterleaved_avi = TRUE; i++; err = RM_OK; } else if ( ! strcmp(argv[i], "-monitor")) { options->monitorFIFOs = TRUE; err = RM_OK; i++; } else if ( ! strcmp(argv[i], "-fopen")) { if (argc > i+1) { options->internal_file_open = strtol(argv[i+1], NULL, 10); i+=2; err = RM_OK; } else err = RM_ERROR; } *index = i; return err;}static void show_private_options(void){ fprintf(stderr, "AVI OPTIONS (default values inside brackets)\n" "\t-at track: Selects audio track number track [0]\n" "\t-fopen <0|1>: use internal file open [0]\n" "\t-force_ni_avi: force playback of non interleaved avi files [FALSE]\n");}static void show_usage(char *progname){ show_private_options(); show_playback_options(); show_display_options(); show_video_options(); show_audio_options(); fprintf(stderr, "--------------------------------\n"); fprintf(stderr, "Minimum cmd line: %s <file name>\n", progname); fprintf(stderr, "--------------------------------\n"); exit(1);}static void parse_cmdline(int argc, char *argv[]){ int i; RMstatus err; if (argc < 2) show_usage(argv[0]); i = 1; while ((argc > i)) { if (argv[i][0] != '-') { if (play_opt->filename == NULL) { play_opt->filename = argv[i]; i++; } else show_usage(argv[0]); } else { err = parse_private_cmdline(argc, argv, &i, &priv_opt); if (err == RM_ERROR) show_usage(argv[0]); if (err != RM_PENDING) continue; err = parse_playback_cmdline(argc, argv, &i, play_opt); if (err == RM_ERROR) show_usage(argv[0]); if (err != RM_PENDING) continue; err = parse_display_cmdline(argc, argv, &i, disp_opt); if (err == RM_ERROR) show_usage(argv[0]); if (err != RM_PENDING) continue; err = parse_video_cmdline(argc, argv, &i, video_opt); if (err == RM_ERROR) show_usage(argv[0]); if (err != RM_PENDING) continue; err = parse_audio_cmdline2(argc, argv, &i, audio_opt, MAX_AUDIO_DECODER_INSTANCES, &audioInstances); if (RMFAILED(err)) show_usage(argv[0]); } } if (play_opt->filename == NULL) show_usage(argv[0]);}#endifstatic RMstatus SyncTimerWithDecoderPTS(struct avi_context *avi_info){ RMuint64 videoPTS; RMuint64 CurrentSTC; RMstatus err = RM_OK; RMuint64 time = 0; DCCSTCGetTime(avi_info->dcc_info->pStcSource, &CurrentSTC, avi_info->vopTimeIncrementResolution); time = round_int_div(CurrentSTC, avi_info->vopTimeIncrementResolution); RMDBGLOG((ENABLE, "stc is %llu/%lu = %llu s\n", CurrentSTC, avi_info->vopTimeIncrementResolution, time)); err = RUAGetProperty(avi_info->pRUA, avi_info->dcc_info->SurfaceID, RMGenericPropertyID_CurrentDisplayPTS, &videoPTS, sizeof(videoPTS)); if (err != RM_OK) { RMDBGLOG((ENABLE, "error %d while getting CurrentDisplayPTS\n", err)); return err; } if (avi_info->vopTimeIncrementResolution == 90000) videoPTS *= 2;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -