- 浏览: 231406 次
- 性别:
- 来自: 南京
最新评论
-
baby8117628:
vc下mp3 IDv1和IDV2的读取 -
gezexu:
你好,我按照你的步骤一步步进行但是安装libvorbis的时候 ...
linux如何搭建强大的FFMPEG环境 -
ini_always:
帅哥,转载也把格式做好点,另外出处也要注明一下吧。。。
MP3文件格式解析
今天突发奇想,就在以前音频播放器(详细情况请看这里——http://blog.csdn.net/baymoon/archive/2006/11 /16/1388693.aspx)的基础上用ffmpeg写了个简单的多媒体播放器,这里把源代码贴出来,供大家参评;这里的多媒体播放,并没有用到什么很强大的音视频同步技术,而只是简单的使用了视频随着音频同步,想必你看了代码之后会有所悟的。。。不多说了,看代码。。。
/*************************************************************************** * main.cc * * Thu Nov 9 20:47:33 2006 * Copyright 2006 * Email lsosa.cs2c ****************************************************************************/ #include <avcodec.h> #include <avformat.h> #include <avutil.h> #include <assert.h> #include <stdio.h> #include <stdlib.h> #include <X11/Xlib.h> #include <sys/soundcard.h> #include <sys/stat.h> #include <fcntl.h> #include <sys/ioctl.h> #include <unistd.h> #include <errno.h> #include <string.h> #include <sched.h> #include <SDL/SDL.h> #define ALL_DEBUG #ifdef ALL_DEBUG #define AV_DEBUG #define AUDIO_DEBUG #endif //------------------------------------------------------------------------------ // manipulations for file int open_file (char *file_name, int mode) ...{ // open file file_name and return the file descriptor; int fd; if ((fd = open (file_name, mode)) < 0) ...{ fprintf (stderr, " Can't open %s! ", file_name); exit (-1); } return fd; } int set_audio (int fd, AVCodecContext * pCodecCtx) ...{ // set the properties of audio device with pCodecCtx; int i, err; /**//* 设置适当的参数,使得声音设备工作正常 */ /**//* 详细情况请参考Linux关于声卡编程的文档 */ i = 0; ioctl (fd, SNDCTL_DSP_RESET, &i); i = 0; ioctl (fd, SNDCTL_DSP_SYNC, &i); i = 1; ioctl (fd, SNDCTL_DSP_NONBLOCK, &i); // set sample rate; #ifdef AUDIO_DEBUG printf ("pCodecCtx->sample_rate:%d ", pCodecCtx->sample_rate); #endif i = pCodecCtx->sample_rate; if (ioctl (fd, SNDCTL_DSP_SPEED, &i) == -1) ...{ fprintf (stderr, "Set speed to %d failed:%s ", i, strerror (errno)); return (-1); } if (i != pCodecCtx->sample_rate) ...{ fprintf (stderr, "do not support speed %d,supported is %d ", pCodecCtx->sample_rate, i); return (-1); } // set channels; i = pCodecCtx->channels; #ifdef AUDIO_DEBUG printf ("pCodecCtx->channels:%d ", pCodecCtx->channels); #endif if ((ioctl (fd, SNDCTL_DSP_CHANNELS, &i)) == -1) ...{ fprintf (stderr, "Set Audio Channels %d failed:%s ", i, strerror (errno)); return (-1); } if (i != pCodecCtx->channels) ...{ fprintf (stderr, "do not support channel %d,supported %d ", pCodecCtx->channels, i); return (-1); } // set bit format; i = AFMT_S16_LE; if (ioctl (fd, SNDCTL_DSP_SETFMT, &i) == -1) ...{ fprintf (stderr, "Set fmt to bit %d failed:%s ", i, strerror (errno)); return (-1); } if (i != AFMT_S16_LE) ...{ fprintf (stderr, "do not support bit %d, supported %d ", AFMT_S16_LE, i); return (-1); } // set application buffer size; // i = (0x00032 << 16) + 0x000c; // 32 4kb buffer; // ioctl (fd, SNDCTL_DSP_SETFRAGMENT, &i); i = 1; ioctl (fd, SNDCTL_DSP_PROFILE, &i); return 0; } void close_file (int fd) ...{ // close the file pointed by file descriptor fd; close (fd); } //------------------------------------------------------------------------------ // handle audio; void display_AVCodecContext(AVCodecContext *pCodecCtx)...{ // #define STDOUT stderr fprintf(STDOUT, "pCodecCtx->bit_rate:%d ", pCodecCtx->bit_rate); fprintf(STDOUT, "pCodecCtx->sample_rate:%d ", pCodecCtx->sample_rate); fprintf(STDOUT, "pCodecCtx->channels:%d ", pCodecCtx->channels); fprintf(STDOUT, "pCodecCtx->frame_size:%d ", pCodecCtx->frame_size); fprintf(STDOUT, "pCodecCtx->frame_number:%d ", pCodecCtx->frame_number); fprintf(STDOUT, "pCodecCtx->delay:%d ", pCodecCtx->delay); fprintf(STDOUT, "pCodecCtx->frame_bits:%d ", pCodecCtx->frame_bits); } // error if return -1; // success if return 0; // 这里要用到指向指针的指针,否则传不到值; int av_init (char *file_name, AVFormatContext ** pFormatCtx, AVCodecContext ** pAudioCodecCtx, int *p_audioStream, AVCodecContext ** pVideoCodecCtx, int *p_videoStream) ...{ // init the codec and format of input file file_name; int audioStream, i; int videoStream; AVCodec *pAudioCodec; AVCodec *pVideoCodec; // catch error assert(file_name != NULL); assert(*pFormatCtx != NULL); assert(*pAudioCodecCtx != NULL); // Register all formats and codecs av_register_all (); // open file if (av_open_input_file (pFormatCtx, file_name, NULL, 0, NULL) != 0)...{ // Couldn't open file fprintf (stderr, " Can't open %s! ", file_name); return -1; } // Retrieve stream information if (av_find_stream_info (*pFormatCtx) < 0)...{ // Couldn't find stream information return -1; } #ifdef AV_DEBUG // Dump information about file onto standard error dump_format (*pFormatCtx, 0, file_name, false); #endif // Find the first audio and video stream respectively audioStream = -1; videoStream = -1; for (i = 0; i < (*pFormatCtx)->nb_streams; i++)...{ if ((*pFormatCtx)->streams[i]->codec->codec_type == CODEC_TYPE_AUDIO) ...{ audioStream = i; }else if ((*pFormatCtx)->streams[i]->codec->codec_type == CODEC_TYPE_VIDEO)...{ videoStream = i; } } #ifdef AV_DEBUG // dump_stream_info(pFormatCtx); #endif // exclude error if (audioStream == -1)...{ // Didn't find a audio or video stream // return -1; printf("No Audio "); } if (videoStream == -1)...{ // Didn't find a audio or video stream // return -1; printf("No Video "); } // Get a pointer to the codec context for the audio stream *pAudioCodecCtx = (*pFormatCtx)->streams[audioStream]->codec; *pVideoCodecCtx = (*pFormatCtx)->streams[videoStream]->codec; // Find the decoder for the audio stream pAudioCodec = avcodec_find_decoder ((*pAudioCodecCtx)->codec_id); pVideoCodec = avcodec_find_decoder ((*pVideoCodecCtx)->codec_id); // if (pAudioCodec == NULL)...{ return -1; // Codec not found } if (pVideoCodec == NULL)...{ return -1; // Codec not found } // Open audio codec if (avcodec_open ((*pAudioCodecCtx), pAudioCodec) < 0)...{ return -1; // Could not open codec } // Open video codec if (avcodec_open ((*pVideoCodecCtx), pVideoCodec) < 0)...{ return -1; // Could not open codec } #ifdef AUDIO_DEBUG // printf ("pCodecCtx->sample_rate:%d, audioStream:%d ", (*pCodecCtx)->sample_rate, audioStream); // display_AVCodecContext(*pCodecCtx); #endif *p_audioStream = audioStream; *p_videoStream = videoStream; return 0; } void av_play (AVFormatContext * pFormatCtx, AVCodecContext * pAudioCodecCtx, int audioStream, AVCodecContext * pVideoCodecCtx, int videoStream) // AVCodecContext * pCodecCtx, int audioStream) ...{ // which was read from one frame; AVPacket packet; uint32_t len; uint8_t decompressed_audio_buf[(AVCODEC_MAX_AUDIO_FRAME_SIZE * 3) / 2]; int decompressed_audio_buf_size; uint8_t * p_decompressed_audio_buf; int fd = -1; // audio file or test file? char filename[64] = "/dev/dsp"; int mode = O_WRONLY; // Video; AVFrame *pFrame; AVFrame *pFrameYUV; int frameFinished; /**////////// SDL initialization SDL_Surface *screen = SDL_SetVideoMode (pVideoCodecCtx->width, pVideoCodecCtx->height, 0, SDL_HWSURFACE); SDL_Overlay *overlay = SDL_CreateYUVOverlay (pVideoCodecCtx->width, pVideoCodecCtx->height, SDL_YV12_OVERLAY, screen); static SDL_Rect rect; rect.x = 0; rect.y = 0; rect.w = pVideoCodecCtx->width; rect.h = pVideoCodecCtx->height; /**/////////// // open audio file or written file // printf("fd:%d", fd); fd = open_file(filename, mode); // printf("fd:%d", fd); // set_audio(fd, pAudioCodecCtx); // printf("(AVCODEC_MAX_AUDIO_FRAME_SIZE * 3) / 2=%d ", (AVCODEC_MAX_AUDIO_FRAME_SIZE * 3) / 2); printf("AVCODEC_MAX_AUDIO_FRAME_SIZE=%d ", AVCODEC_MAX_AUDIO_FRAME_SIZE); // for a test // char test_file[256] = "my_pcm.pcm"; // fd = open_file(test_file, mode); #ifdef AV_DEBUG static int size = 0; #endif // // set the sched priority // 这是为了提高音频优先级;不晓得起作用没; int policy = SCHED_FIFO; sched_setscheduler(0, policy, NULL); // Allocate video frame pFrame = avcodec_alloc_frame (); // Allocate an AVFrame structure pFrameYUV = avcodec_alloc_frame (); if (pFrameYUV == NULL) return; // Set SDL events SDL_EventState (SDL_ACTIVEEVENT, SDL_IGNORE); SDL_EventState (SDL_MOUSEMOTION, SDL_IGNORE); // SDL_ShowCursor (SDL_ENABLE); int write_buf_size = 4196; int written_size; while ((av_read_frame (pFormatCtx, &packet) >= 0) && (SDL_PollEvent (NULL) == 0)) ...{ // Is this a packet from the audio stream? // 判断是否音频帧; if (packet.stream_index == audioStream) ...{ // Decode audio frame // 解码音频数据为pcm数据; len = avcodec_decode_audio (pAudioCodecCtx, (int16_t *)decompressed_audio_buf, &decompressed_audio_buf_size, // it is the decompressed frame in BYTES 解码后的数据大小,字节为单位; packet.data, packet.size ); // printf("len:%d, packet.size:%d ", len, packet.size); // printf("packet.pts:%d packet.dts:%d ", packet.pts, packet.dts); if ( len < 0 )...{ // if error len = -1 printf("+----- error in decoding audio frame "); // exit(0); } // audio_buf_info info; p_decompressed_audio_buf = decompressed_audio_buf; while ( decompressed_audio_buf_size > 0 )...{ // 解码后数据不为零,则播放之,为零,则; written_size = write(fd, p_decompressed_audio_buf, decompressed_audio_buf_size); if ( written_size == -1 )...{ // printf("error:decompressed_audio_buf_size:%d, decompressed_audio_buf_size:%d, %s ", decompressed_audio_buf_size, decompressed_audio_buf_size,strerror(errno)); // usleep(100); continue; } // printf("decompressed_audio_buf_size:%d, written_size:%d ", decompressed_audio_buf_size, written_size); decompressed_audio_buf_size -= written_size; p_decompressed_audio_buf += written_size; }// end while } else if (packet.stream_index == videoStream) ...{ // Decode video frame avcodec_decode_video (pVideoCodecCtx, pFrame, &frameFinished, packet.data, packet.size); // Did we get a video frame? if (frameFinished) ...{ // Convert the image from its native format to YUV, and display SDL_LockYUVOverlay (overlay); pFrameYUV->data[0] = overlay->pixels[0]; pFrameYUV->data[1] = overlay->pixels[2]; pFrameYUV->data[2] = overlay->pixels[1]; pFrameYUV->linesize[0] = overlay->pitches[0]; pFrameYUV->linesize[1] = overlay->pitches[2]; pFrameYUV->linesize[2] = overlay->pitches[1]; img_convert ((AVPicture *) pFrameYUV, PIX_FMT_YUV420P, (AVPicture *) pFrame, pVideoCodecCtx->pix_fmt, pVideoCodecCtx->width, pVideoCodecCtx->height); SDL_UnlockYUVOverlay (overlay); SDL_DisplayYUVOverlay (overlay, &rect); /**//// // SDL_Delay (33); } }// end if // Free the packet that was allocated by av_read_frame av_free_packet (&packet); }// end while of reading one frame; // Free the RGB image av_free (pFrameYUV); // Free the YUV frame av_free (pFrame); // for test lsosa // printf("size = %d ", size / 1024 / 1024 ); SDL_FreeYUVOverlay (overlay); close_file(fd); } void av_close (AVFormatContext * pFormatCtx, AVCodecContext * pAudioCodecCtx, AVCodecContext * pVideoCodecCtx) ...{ // close the file and codec // Close the codec avcodec_close (pAudioCodecCtx); // Close the codec avcodec_close (pVideoCodecCtx); // Close the video file av_close_input_file (pFormatCtx); } //------------------------------------------------------------------------------ int main (int argc, char **argv)...{ // AVFormatContext *pFormatCtx; int audioStream = -1; int videoStream = -1; AVCodecContext *pAudioCodecCtx; AVCodecContext *pVideoCodecCtx; // exclude the error about args; if ( argc != 2 )...{ printf("please give a file name "); exit(0); } // 注意:这里要用到指向指针的指针,是因为这个初始化函数需要对指针的地址进行改动, // 所以,只有这么做,才能达到目的; if ( av_init(argv[1], &pFormatCtx, &pAudioCodecCtx, &audioStream, &pVideoCodecCtx, &videoStream) < 0 )...{ // fprintf(stderr, "error when av_init "); } // play the audio file av_play(pFormatCtx, pAudioCodecCtx, audioStream, pVideoCodecCtx, videoStream); // close all the opend files av_close(pFormatCtx, pAudioCodecCtx, pVideoCodecCtx); }
发表评论
-
vc下mp3 IDv1和IDV2的读取
2010-01-25 10:52 2379/*这是修改后的代码,VC下读ID3v2 & ID3v ... -
ffmpeg提取音频播放器总结
2010-01-21 16:31 5963ffmpeg提取音频播放器总 ... -
ffmpeg开发指南
2010-01-20 17:26 3370ffmpeg 中的Libavformat 和 li ... -
linux下安装ffmpeg过程
2010-01-18 15:48 1883最近互联网视频共享的 ... -
【PNG overview】PNG专题!
2010-01-18 13:39 3347【PNG overview】PNG专题! 作者 鼯鼠 ... -
Big Endian 和 Little Endian
2010-01-18 13:29 1542Peter Lee 2008-04-20 一、字节序 ... -
MediaInfo开源工程
2010-01-18 13:22 2354一、简介 MediaInfo 用来 ... -
MP3文件格式解析
2010-01-18 10:58 3542MP3文件格式解析 Peter Lee 2008-06-0 ... -
LAME-mp3
2010-01-18 10:40 2010LAME - 压缩 MP3 的最佳利 ... -
FLV文件格式分析(图示讲解的清楚)
2010-01-14 15:56 5090FLV是一个二进制文件, ... -
我对FLV 文件格式的理解
2010-01-14 15:52 3345我对FLV 文件格式的理解 ----------------- ... -
常用的音频文件介绍
2010-01-13 10:56 1364MP3全称是动态影像专家压缩标准音频层面3(Moving Pi ... -
RTSP客户端的JAVA实现
2010-01-12 16:12 8235参考资料 1. 《RTSP简单命 ... -
国外嵌入式、音视频处理等重要网站
2010-01-08 10:07 2017嵌入式方面: 1.关于嵌入式开发的站点,提供非常多关于嵌入 ... -
RTSP点播——消息流程实例
2010-01-08 09:44 5096RTSP点播消息流程实例(客户端:VLC, RTSP服务器:L ... -
live555代码解读之三:SETUP和PLAY请求消息处理过程
2010-01-08 09:43 3442SETUP请求消息处理过程 ... -
live555代码解读之二:DESCRIBE请求消息处理过程
2010-01-08 09:42 3776ve555代码解读之二:DESCRIBE请求消息处理过程 ... -
live555代码解读之一:RTSP连接的建立过程
2010-01-08 09:42 4432TSPServer类用于构建一个RTSP服务器,该类同时在其内 ... -
live555源代码概述
2010-01-08 09:41 3862述 liveMedia项目(http://www ... -
浅议SDP(会话描述协议)
2010-01-04 15:25 3532因为最近常常使用到SDP(会话描述协议Session Desc ...
相关推荐
Android ffmpeg视频播放器源代码,可以直接播放H264的视频流数据
ffmpeg播放器C#库封装,RTMP直播播放器,播放器支持gpu硬解
关于 FFmpeg 是多媒体程序核心开源库,涉及广播电视行业、视频监控行业、互联网视 频行业等,涉及流媒体、音视频编解码、容器、格式转换、以及后期处理等技术。 本书旨在让更多的人深入理解 FFmpeg 框架库,通过使用...
Qt+FFMPEG+SDL实现的视频播放器 包含源代码和可执行程序
FFmpeg编写一个简单播放器详细步骤介绍, 音频,视频同步
《ffmpeg基础库编程开发》482页 目录 第一章 多媒体概念介绍 6 第二章 FFmpeg框架 34 第三章 编译及简单应用 41 第四章 数据结构 57 第五章 重要模块 76 第六章 播放器 243 第七章 应用开发 275 第八章 关键...
ffmpeg 库的最新源代码 2010年3月2日的
基于C++ Qt+FFMPEG+SDL2写的视频播放器源代码,可以播放本地视频
ffmpeg和sdl编写播放器代码的实例,包括文档解释说明, 对学习ffmpeg很有帮助。
ffmpeg最新源代码,ffmpeg最新源代码,ffmpeg最新源代码,ffmpeg最新源代码,ffmpeg最新源代码,ffmpeg最新源代码,
ffmpeg源代码,用C编写。ffmpeg是一个视频处理的开源程序,可以用来将视频转换为flv格式。
QT+ffmpeg+多线程的视频播放器,实现边解码视频边在窗口播放的效果
Android实例源码-音乐播放器类安卓源代码(9例) Android多线程断点续传下载+在线播放音乐 GL音乐播放器 基于SDL、FFmpeg的android播放器源码 简单实用的音乐播放器 简单音乐播放器,实现了播放器基本功能,使用...
ffmpeg基础库开发技术,介绍ffmpeg api的使用,多媒体开发必不可少的技能。 1. AVFormatContext:就是对容器或者媒体文件层次的抽象。 2. AVStream:在文件中(容器里面)包含了多路流(音频流、视频流、字幕流),...
将ffplay代码改写成c++并封装成库,只解析了视频,去掉了源码中的音频和字幕部分,软件有播放、关闭、截图、录像等功能,播放器界面是用QT做的
使用最新ffmpeg制作的视频播放器,注释很详细!适合新手学习~可以在6410开发板上运行,需要SDL库。
FFMPEG是一个很好的库,可以用来创建视频应用或者生成特定的工具。FFMPEG几乎为你把所有的繁重工作都做了,比 如解码、编码、复用和解复用。这使得多媒体应用程序变得容易编写。它是一个简单的,用C编写的,快速的...
最新版的ffmpeg源代码,供大家下载使用
雷神在“广播电视工程大二的暑假小学期的课程设计”中,课程内容为《基于 FFmpeg + SDL 的视频播放器的制作》,其中有个示例代码,代码的工程名为simplest_video_play_sdl2。我在vs2017中打开编译此代码时出现了问题...