大家好
我最近在用ffmpeg写一个能在arm-linux嵌入式系统上运行的视频播放器
我首先在ubuntu PC机上写了个正常运行的视频播放器,但是这个播放器程序用到了SDL,而我的arm-linux嵌入式系统不支持SDL,所以我打算用纯C语言来实现我的播放器,也就是不用SDL库的API函数。
花了半个月的时间终于写好了,运行在我的arm-linux嵌入式系统上,视频播放一切正常,但是播放出来的音频却是断断续续的,用了两天的时间也没有找出是什么原因。
我把我的源代码贴出来,大侠帮我看看啊。
先谢谢大家。
#include
#include
#include
#include
#include
#include
#include "/media/disk/T11_SDE/CMD/include/bio_func.h"
// Global function
static void SetAudioArgument(int Samplebits, int Channels, int SamplesPerSec);
// Global variable
int w_dsp;//用来打开音频设备的
/*
* NAME:main()
* DESCRIPTION:program entry point
*/
int main (int argc, const char * argv[])
{
AVFormatContext *pFormatCtx;
int i, videoStream, audioStream;
AVCodecContext *pCodecCtx;
AVCodec *pCodec;
AVFrame *pFrame;
AVFrame *pFrameRGB;
uint8_t *buffer;
int numBytes;
AVPacket packet;
int frameFinished;
AVCodecContext *aCodecCtx;
AVCodec *aCodec;
static uint8_t audio_buf[(AVCODEC_MAX_AUDIO_FRAME_SIZE * 3) / 2];
int audio_size;
/* if(argc streams[i]->codec->codec_type==CODEC_TYPE_VIDEO && videoStream streams[i]->codec->codec_type==CODEC_TYPE_AUDIO && audioStream streams[audioStream]->codec;
// Find the decoder for the audio stream
aCodec = avcodec_find_decoder(aCodecCtx->codec_id);
if(!aCodec) {
fprintf(stderr, "Unsupported codec!n");
return -1; // Audio codec not found
}
//Open audio codec
if(avcodec_open(aCodecCtx, aCodec)streams[videoStream]->codec;
// Find the decoder for the video stream
pCodec=avcodec_find_decoder(pCodecCtx->codec_id);
if(pCodec==NULL)
return -1; // Video codec not found
// Open video codec
if(avcodec_open(pCodecCtx, pCodec)time_base.num>1000 && pCodecCtx->time_base.den==1)
pCodecCtx->time_base.den=1000;
// Allocate video frame
pFrame=avcodec_alloc_frame();
// Alllocate an AVFrame structure
pFrameRGB=avcodec_alloc_frame();
if(pFrameRGB==NULL)
return -1;
// Determine required buffer size and allocate buffer
numBytes=avpicture_get_size(PIX_FMT_RGB565,pCodecCtx->width,pCodecCtx->height);
buffer=malloc(numBytes);
// Assign appropriate parts of buffer to image planes in pFrameRGB
avpicture_fill((AVPicture *)pFrameRGB,buffer,PIX_FMT_RGB565,pCodecCtx->width,pCodecCtx->height);
SetAudioArgument(16, aCodecCtx->channels, aCodecCtx->sample_rate);
// Read frames and save first five frames to disk
while(av_read_frame(pFormatCtx, &packet)>=0)
{
// Is this a packet from the video stream?
if(packet.stream_index==videoStream)
{
// Decode video frame
avcodec_decode_video(pCodecCtx, pFrame, &frameFinished,
packet.data, packet.size);
// Did we get a video frame?
if(frameFinished)
{
static struct SwsContext *img_convert_ctx;
// Convert the image into RGB format that T11 uses
if(img_convert_ctx == NULL)
{
int w = pCodecCtx->width;
int h = pCodecCtx->height;
img_convert_ctx = sws_getContext(w, h, pCodecCtx->pix_fmt, w, h,
PIX_FMT_RGB565, SWS_BICUBIC,NULL, NULL, NULL);
if(img_convert_ctx == NULL)
{
fprintf(stderr, "Cannot initialize the conversion context!n");
exit(1);
}
}
int ret = sws_scale(img_convert_ctx, pFrame->data, pFrame->linesize, 0,
pCodecCtx->height, pFrameRGB->data, pFrameRGB->linesize);
// Write the frame data to T11's FrameBuffer
if(write(fbs.filefb, (void *)buffer, numBytes) == -1)
{
printf ("fb write date error.n");
perror ("fb write");
usleep (40000);
}
if(_bioskey(1))
{
goto Exit;
}
}
} else if(packet.stream_index==audioStream) { // Is this a packet from the audio stream?
//出现断断续续的声音,我觉得原因出现在这里,但是我的流程好像又没有错。
audio_size=sizeof(audio_buf);
avcodec_decode_audio2(aCodecCtx, (int16_t *)audio_buf, &audio_size,packet.data, packet.size);
write(w_dsp,audio_buf,audio_size);//将解码出来的声音数据写到我的音频设备里
}
// Free the packet that was allocated by av_read_frame
av_free_packet(&packet);
}
Exit:
// Free the packet that was allocated by av_read_frame
av_free_packet(&packet);
// Free the RGB image
free(buffer);
av_free(pFrameRGB);
// Free the YUV frame
av_free(pFrame);
// Close the codec
avcodec_close(pCodecCtx);
avcodec_close(aCodecCtx);
// Close the video file
av_close_input_file(pFormatCtx);
close (w_dsp);
return 0;
}
/*
* NAME:SetAudioArgument()
* DESCRIPTION:Set the audio equipment argument
*/
static void SetAudioArgument(int Samplebits, int Channels, int SamplesPerSec)
{
int arg;
int status;
w_dsp = open ("/dev/dsp", O_RDWR);
if (w_dsp