ffmpeg开发指南(经典)
ffmpeg 和 SDL 教程
ffmpeg 编程手册
ffmpeg 编程手册ffmpeg 是一款强大的多媒体处理工具,它提供了丰富的功能和灵活的编程接口,使得开发者可以轻松地进行音视频处理和转码。
本篇文章将为您介绍 ffmpeg 的编程手册,帮助您更好地了解和使用这个工具。
一、ffmpeg 简介ffmpeg 是一个开源的跨平台音视频处理工具,它可以实现音视频的录制、转码、剪辑、合并等功能。
ffmpeg 支持众多的音视频格式,包括但不限于 MP4、AVI、FLV、MKV、MP3、AAC 等。
它不仅可以处理本地文件,还可以通过网络流进行实时的音视频处理。
ffmpeg 不仅仅是一个命令行工具,它还提供了丰富的库函数,可以供开发者进行二次开发。
二、ffmpeg 的编程接口ffmpeg 提供了丰富的编程接口,可以通过这些接口来实现音视频处理的自动化。
其中最常用的接口包括 libavformat、libavcodec、libavutil 等。
libavformat 提供了音视频格式的封装和解封装功能,可以读取和写入各种音视频格式的文件。
libavcodec 提供了音视频编解码功能,可以将音视频数据进行压缩和解压缩。
libavutil 则提供了一些常用的工具函数,例如内存管理、时间处理等。
三、ffmpeg 的基本用法在使用 ffmpeg 进行编程时,首先需要初始化 ffmpeg 的环境。
可以通过调用 av_register_all() 函数来完成初始化。
接下来,可以通过 avformat_open_input() 函数打开输入文件,通过avformat_find_stream_info() 函数获取音视频流信息。
然后,可以使用 avcodec_find_decoder() 函数找到音视频解码器,并通过avcodec_open2() 函数打开解码器。
在解码音视频数据后,可以将解码后的数据进行处理,例如转码、剪辑、合并等。
对于音频数据,可以使用 swr_convert() 函数进行采样率、声道数的转换。
org.bytedeco use system ffmpeg -回复
org.bytedeco use system ffmpeg -回复如何使用org.bytedeco 库中的system ffmpeg导语:ffmpeg 是一款广泛应用的开源音视频处理工具,而org.bytedeco 则是一个提供了在Java中使用ffmpeg的库。
本文将介绍如何使用org.bytedeco 库的system ffmpeg 功能,并提供一个步骤指南。
第一步:了解org.bytedeco 库org.bytedeco 是一个开源的项目,它提供了一系列的跨平台的Java库,这些库的目的是通过Java接口来访问不同的底层库。
这些库包括OpenCV、ffmpeg等。
其中,system ffmpeg 是org.bytedeco 库中的一个模块,它提供了在Java中使用ffmpeg的功能。
第二步:安装org.bytedeco 库要使用org.bytedeco 库,首先需要将其安装到Java开发环境中。
可以通过以下步骤完成安装:1. 访问org.bytedeco 官方网站(2. 解压下载的库文件。
3. 将解压后的库文件添加到Java的classpath中。
可以使用IDE(如Eclipse或IntelliJ)进行配置,或者手动在命令行中设置CLASSPATH环境变量。
安装完成后,你就可以开始使用org.bytedeco 库了。
第三步:使用org.bytedeco 的system ffmpeg现在你可以使用org.bytedeco 的system ffmpeg 模块进行音视频处理了。
以下是一些常见的用法:1. 转码:你可以使用org.bytedeco.system.ffmpeg.FFmpeg 类的transcode 方法来进行音视频的转码。
这个方法接受输入文件的路径、输出文件的路径以及一组转码选项作为参数。
以下是一个示例:javaimport org.bytedeco.system.ffmpeg.FFmpeg;public class Transcoder {public static void main(String[] args) {String inputFile = "input.mp4";String outputFile = "output.mp4";String[] options = {"-c:v", "libx264", "-c:a", "aac"};FFmpeg.transcode(inputFile, outputFile, options);}}这个示例将输入文件input.mp4 转码为输出文件output.mp4,并使用libx264 编码器进行视频编码,aac 编码器进行音频编码。
(原)ffmpeg过滤器开发和理解
(原)ffmpeg过滤器开发和理解最近学习了ffmpeg关于filter过滤器的开发,关于中间的⼏个相关概念,我们先放在简单介绍⼀下:AVFilterGraph:⼏乎完全等同与directShow中的fitlerGraph,代表⼀串连接起来的filter们.AVFilter:代表⼀个filter.AVFilterPad:代表⼀个filter的输⼊或输出⼝,等同于DShow中的Pin.只有输出pad的filter叫source,只有输⼊pad的tilter叫sink.AVFilterLink:代表两个连接的fitler之间的粘合物.然后分别看下各⾃的结构定义1,过滤器结构体定义:1struct AVFilter{2const char * name;//过滤器名称。
34const char * description;//过滤器说明。
56const AVFilterPad * inputs;//输⼊列表,由零元素终⽌。
78const AVFilterPad * outputs;//输出列表,由零元素终⽌。
910const AVClass * priv_class;//私有数据类,⽤于声明过滤器私有AVOptions。
1112int flags;//AVFILTER_FLAG_ *的组合。
1314int(* init )(AVFilterContext *ctx);//过滤初始化函数。
1516//应该通过想要将AVOptions的字典传递给在init中分配的嵌套上下⽂的过滤器来设置⽽不是init。
17int(* init_dict )(AVFilterContext *ctx, AVDictionary **options);1819//过滤器在其输⼊和输出上⽀持的查询格式20void(* uninit )(AVFilterContext *ctx);2122//要为过滤器分配的私有数据的⼤⼩23int priv_size;2425//avfilter的附加标志仅供内部使⽤。
FFmpeg用户指南说明书
Table of ContentsAbout1 Chapter 1: Getting started with ffmpeg2 Remarks2 Examples2 Installation or Setup2 OS X2 Windows2 Unix3 What is FFmpeg?3 Chapter 2: Decoding4 Introduction4 Examples4 Find a stream4 Open a codec context4 Decode frames5 Chapter 3: Ffmpeg Restream7 Examples7 Simple Device Restream7 Chapter 4: Reading Media8 Introduction8 Examples8 Reading from memory8 Reading from a file9 Reading from a format context9 Reading from an IStream in a IOContext9 Seeking within an IStream in an IOContext10 Credits11AboutYou can share this PDF with anyone you feel could benefit from it, downloaded the latest version from: ffmpegIt is an unofficial and free ffmpeg ebook created for educational purposes. All the content is extracted from Stack Overflow Documentation, which is written by many hardworking individuals at Stack Overflow. It is neither affiliated with Stack Overflow nor official ffmpeg.The content is released under Creative Commons BY-SA, and the list of contributors to each chapter are provided in the credits section at the end of this book. Images may be copyright of their respective owners unless otherwise specified. All trademarks and registered trademarks are the property of their respective company owners.Use the content presented in this book at your own risk; it is not guaranteed to be correct nor accurate, please send your feedback and corrections to ********************Chapter 1: Getting started with ffmpeg RemarksFFMpeg This section provides an overview of what ffmpeg is, and why a developer might want to use it.It should also mention any large subjects within ffmpeg, and link out to the related topics. Since the Documentation for ffmpeg is new, you may need to create initial versions of those related topics.ExamplesInstallation or SetupFFmpeg can be installed on a mixture of Operating Systems, including Unix and OS X. Using a command line extension, this utility can also be installed on Windows using a dll.OS XTo install this utility on OS X, just head over to , download the release relative to your Macs architecture (instructions on finding this can be found here). Then put the application into an accessible directory and run it from command line.Another way is using HomeBrew: https:///211541/homebrew-for-os-x-easily-installs-desktop-apps-and-terminal-utilities/For examplebrew install ffmpeg --with-fdk-aac --with-ffplay --with-libass --with-libvorbis --with-libvpx --with-rtmpdump --with-openh264 --with-toolsWindowsTo install this utility on Windows, head over to[](https:///download.html#build-windows) and follow the download link, using your architecture. Instructions on finding this can be seen[here](/en-us/windows/forum/windows_7-hardware/i-need-to-know-how-to-determine-my-processors/3ede9c69-25f5-427b-8e8d-e9dd2d032d22). Then place the downloaded software into an accessible directory and run from command line.UnixTo install this utility on Unix, just follow the instructions found at[](https:///download.html#build-linux)To check if ffmpeg is installed correctly and see a list of available commands try running the following command in the command line:ffmpeg -helpWhat is FFmpeg?FFmpeg (or "Fast Forward MPEG") is a simple yet feature rich command line utility to allow the manipulation (including decoding, encoding, transcoding, muxing, demuxing, streaming, filtering, and playing) of media and video files. This utility differs from other GUI orientated software as it employs the WYSIWYG methodology (What You See Is What You Get). Instead of hidden away menus and features, everything can be found by just typing ffmpeg -h when set up, or following the comprehensive documentation. In addition to the command line tool there are a number of C libraries (which it uses), that can be used to bring the functionality of FFmpeg into other projects. The documentation for the libraries includes many examples to help get you started.Read Getting started with ffmpeg online: https:///ffmpeg/topic/4935/getting-started-with-ffmpegChapter 2: DecodingIntroductionGetting the raw video/audio from encoded media streams.ExamplesFind a streamMedia stream containers usually have a several streams, such as a video stream and an audio stream. For example, you can get the audio stream using the following:// A Format Context - see Reading Data for more infoAVFormatContext *formatContext;// Inspect packets of stream to determine propertiesif (avformat_find_stream_info(formatContext, NULL) < 0){// Error finding info}// Find the stream and its codecAVCodec* audioCodec;int audioStreamIndex = av_find_best_stream(formatContext, // The media streamAVMEDIA_TYPE_AUDIO, // The type of stream we are looking for - audio for example-1, // Desired stream number, -1 for any-1, // Number of related stream, -1 for none&audioCodec, // Gets the codec associated with the stream, can be NULL0 // Flags - not used currently);if(audioStreamIndex = AVERROR_STREAM_NOT_FOUND || !audioCodec){// Error finding audio (ie. no audio stream?)}To get other types of streams, you just need to replace the type of stream. The following are valid types:AVMEDIA_TYPE_VIDEO,AVMEDIA_TYPE_AUDIO,AVMEDIA_TYPE_SUBTITLE,AVMEDIA_TYPE_DATA, // Usually continuousAVMEDIA_TYPE_ATTACHMENT, // Usually sparseOpen a codec contextOnce you have a stream Format Context and its respective Codec, you can open it for decoding using the following code:// The format context and codec, given - see Find a stream for how to get theseAVFormatContext *formatContext;AVCodec* codec;int streamIndex;// Get the codec contextAVCodecContext *codecContext = avcodec_alloc_context3(codec);if (!codecContext){// Out of memoryavformat_close_input(&formatContext);}// Set the parameters of the codec context from the streamint result = avcodec_parameters_to_context(codecContext,formatContext->streams[streamIndex]->codecpar);if(result < 0){// Failed to set parametersavformat_close_input(&formatContext);avcodec_free_context(&codecContext);}// Ready to open stream based on previous parameters// Third parameter (NULL) is optional dictionary settingsif (avcodec_open2(codecContext, codec, NULL) < 0){// Cannot open the video codeccodecContext = nullptr;}// Do something with the opened codec context... (ie decode frames through the context) Decode framesGiven a codec context and encoded packets from a media stream, you can start decoding media into raw frames. To decode a single frame, you can use the following code:// A codec context, and some encoded data packet from a stream/file, given.AVCodecContext *codecContext; // See Open a codec contextAVPacket *packet; // See the Reading Media topic// Send the data packet to the decoderint sendPacketResult = avcodec_send_packet(codecContext, packet);if (sendPacketResult == AVERROR(EAGAIN)){// Decoder can't take packets right now. Make sure you are draining it.}else if (sendPacketResult < 0){// Failed to send the packet to the decoder}// Get decoded frame from decoderAVFrame *frame = av_frame_alloc();int decodeFrame = avcodec_receive_frame(codecContext, frame);if (decodeFrame == AVERROR(EAGAIN)){// The decoder doesn't have enough data to produce a frame// Not an error unless we reached the end of the stream// Just pass more packets until it has enough to produce a frameav_frame_unref(frame);av_freep(frame);}else if (decodeFrame < 0){// Failed to get a frame from the decoderav_frame_unref(frame);av_freep(frame);}// Use the frame (ie. display it)If you want to decode all frames, you can simply place the previous code in a loop, feeding it consecutive packets.Read Decoding online: https:///ffmpeg/topic/10090/decodingChapter 3: Ffmpeg RestreamExamplesSimple Device RestreamFfmpeg is a swiss knife for streaming project. For any kind of device streaming you only need to get the specification of device. To list the deviceffmpeg -f dshow -list_devices true -i dummyCommand prompt will list all the aviable device on machine.[dshow @ 0000000004052420] DirectShow video devices[dshow @ 0000000004052420] "ManyCam Virtual Webcam"[dshow @ 0000000004052420] "UScreenCapture"[dshow @ 0000000004052420] DirectShow audio devicesFor restreaming the audio&video device,ffmpeg -f dshow -i video="DirectShow video devices":audio="DirectShow audio devices"-vcodec libx264 -acodec aac -strict experimental 2 -tune zerolatency -f flvrmtp://WOWZA_IP/WOWZA_APP/STREAMNAMEThis can be extended all kind of device like medical devices or video hardware.Read Ffmpeg Restream online: https:///ffmpeg/topic/9517/ffmpeg-restreamChapter 4: Reading MediaIntroductionThere are a few ways to read Audio/Video into FFmpeg.ExamplesReading from memorylibavformat usually takes in a file name and reads media directly from the filesystem. If you want to read from memory (such as streams), do the following:// Define your buffer sizeconst int FILESTREAMBUFFERSZ = 8192;// A IStream - you choose where it comes fromIStream* fileStreamData;// Alloc a buffer for the streamunsigned char* fileStreamBuffer = (unsigned char*)av_malloc(FILESTREAMBUFFERSZ);if (fileStreamBuffer == nullptr){// out of memory}// Get a AVContext streamAVIOContext* ioContext = avio_alloc_context(fileStreamBuffer, // BufferFILESTREAMBUFFERSZ, // Buffer size0, // Buffer is only readable - set to 1 for read/writefileStreamData, // User (your) specified dataFileStreamRead, // Function - Reading Packets (see example)0, // Function - Write PacketsFileStreamSeek // Function - Seek to position in stream (see example));if(ioContext == nullptr){// out of memory}// Allocate a AVContextAVFormatContext *formatContext = avformat_alloc_context();// Set up the Format ContextformatContext->pb = ioContext;formatContext->flags |= AVFMT_FLAG_CUSTOM_IO; // we set up our own IO// Open "file" (open our custom IO)// Empty string is where filename would go. Doesn't matter since we aren't reading a file// NULL params are format and demuxer settings, respectivelyif (avformat_open_input(&formatContext, "", nullptr, nullptr) < 0){// Error opening file}// Do something with the formatContext// Free resources!avformat_close_input(&formatContext);av_free(ioContext);Reading from a fileOpening a media file from the local file system.AVFormatContext *formatContext;// Open the fileif(avformat_open_file(&formatContext, "path/to/file.ogg", NULL, NULL) < 0){// Error opening file}// Do something with the file// Free resourcesavformat_close_input(&formatContext);Reading from a format contextFormats contain one or more encoded and muxed streams. We usually read these in chunks, which are often called frames (though in certain cases, FFmpeg refers exclusively to decoded, raw media chunks as frames, and encoded chunks as packets, which may be confusing). To read a single frame from a format, use the following:// A Format Context - see other examples on how to create itAVFormatContext *formatContext;// Initialize the AVPacket manuallyAVPacket avPacket;av_init_packet(&avPacket); // set fields of avPacket to default.avPacket.data = NULL;avPacket.size = 0;// Read from the context into the packetif(av_read_frame(formatContext, &avPacket) == 0){// nothing read}// Use the packet (such as decoding it and playing it)// Free packetav_packet_unref(&avPacket);Reading from an IStream in a IOContextThe API call avio_alloc_context, which sets up a custom IO context, takes in a pointer to a Read function. If you are reading from an IStream, you can use the following:/*** Reads from an IStream into FFmpeg.** @param ptr A pointer to the user-defined IO data structure.* @param buf A buffer to read into.* @param buf_size The size of the buffer buff.** @return The number of bytes read into the buffer.*/int FileStreamRead(void* ptr, uint8_t* buf, int buf_size){// This is your IStreamIStream* stream = reinterpret_cast<IStream*>(ptr);ULONG bytesRead = 0;HRESULT hr = stream->Read(buf, buf_size, &bytesRead);if(hr == S_FALSE)return AVERROR_EOF; // End of fileif(FAILED(hr))return -1;return bytesRead;}Seeking within an IStream in an IOContextThe API call avio_alloc_context, which sets up a custom IO context, takes in a pointer to a Seek function. If you are reading from an IStream, you can use the following:/*** Seeks to a given position on an IStream.** @param ptr A pointer to the user-defined IO data structure.* @param pos The position to seek to.* @param origin The relative point (origin) from which the seek is performed.** @return The new position in the IStream.*/int64_t FileStreamSeek(void* ptr, int64_t pos, int origin){// Your custom IStreamIStream* stream = reinterpret_cast<IStream*>(ptr);// Prevent overflowsLARGE_INTEGER in = { pos };ULARGE_INTEGER out = { 0 };// Origin is an item from STREAM_SEEK enum.// STREAM_SEEK_SET - relative to beginning of stream.// STREAM_SEEK_CUR - relative to current position in stream.// STREAM_SEEK_END - relative to end of stream.if(FAILED(stream->Seek(in, origin, &out)))return -1;// Return the new positionreturn out.QuadPart;}Read Reading Media online: https:///ffmpeg/topic/10089/reading-mediaCredits。
ffmpeg 6.0使用手册
文章内容:一、介绍ffmpeg是一个广泛使用的开源多媒体工具包,可以用于录制、转换和流化音频和视频。
在本文中,我们将详细介绍ffmpeg 6.0的使用手册,以便读者能够更好地了解和使用这一工具。
二、安装和运行要使用ffmpeg 6.0,首先需要进行安装。
在Linux系统中,可以通过包管理器进行安装;在Windows系统中,可以下载预编译的可执行文件。
安装完成后,可以通过命令行终端运行ffmpeg,进行音视频处理操作。
三、基本命令ffmpeg提供了丰富的命令,可以进行音视频处理、转码、剪辑等操作。
常用的命令包括:- `-i`:指定输入文件- `-c`:指定编解码器- `-f`:指定输出格式- `-ss`:指定起始时间- `-t`:指定持续时间- `filterplex`:复杂过滤器的使用四、高级功能除了基本命令外,ffmpeg还提供了许多高级功能,包括:- 多路转码:可以同时对多个音视频流进行转码处理- 实时流化:可以将音视频实时流化到网络- 视频编辑:可以对视频进行裁剪、拼接、滤镜等操作五、个人观点ffmpeg是一个功能强大、灵活多样的多媒体工具,可以满足各种音视频处理需求。
通过学习和使用ffmpeg 6.0,不仅可以提升音视频处理能力,还可以为个人和企业带来更多的创造和商业机会。
六、总结在本文中,我们详细介绍了ffmpeg 6.0的使用手册,包括安装和运行、基本命令、高级功能等内容。
通过阅读本文,希望读者能够更全面地了解和掌握ffmpeg 6.0,从而在音视频处理领域取得更好的成就。
以上就是我撰写的关于ffmpeg 6.0使用手册的文章。
希望对你有所帮助!七、应用场景ffmpeg 6.0在实际应用中有广泛的场景,包括但不限于以下几个方面:1. 视频编辑和制作:通过ffmpeg可以轻松实现视频的剪辑、拼接、添加滤镜、调整画面亮度、对比度等操作,是视频编辑和制作领域的利器。
2. 音频处理和转换:除了视频处理,ffmpeg也可以用于音频领域,包括音频格式转换、音频剪辑、音频合并等,满足了音频处理的需求。
FFMPEG教程02指导2:输出到屏幕
SDL和视频为了在屏幕上显示,我们将使用SDL.SDL是Simple Direct Layer的缩写。
它是一个出色的多媒体库,适用于多平台,并且被用在许多工程中。
你可以从它的官方网站的网址/上来得到这个库的源代码或者如果有可能的话你可以直接下载开发包到你的操作系统中。
按照这个指导,你将需要编译这个库。
(剩下的几个指导中也是一样)SDL库中有许多种方式来在屏幕上绘制图形,而且它有一个特殊的方式来在屏幕上显示图像――这种方式叫做YUV覆盖。
YUV(从技术上来讲并不叫YUV而是叫做YCbCr)是一种类似于RGB方式的存储原始图像的格式。
粗略的讲,Y是亮度分量,U和V是色度分量。
(这种格式比RGB复杂的多,因为很多的颜色信息被丢弃了,而且你可以每2个Y有1个U和1个V)。
SDL的YUV覆盖使用一组原始的YUV数据并且在屏幕上显示出他们。
它可以允许4种不同的YUV格式,但是其中的YV12是最快的一种。
还有一个叫做YUV420P的YUV格式,它和YV12是一样的,除了U和V分量的位置被调换了以外。
420意味着它以4:2:0的比例进行了二次抽样,基本上就意味着1个颜色分量对应着4个亮度分量。
所以它的色度信息只有原来的1/4。
这是一种节省带宽的好方式,因为人眼感觉不到这种变化。
在名称中的P表示这种格式是平面的――简单的说就是Y,U和V分量分别在不同的数组中。
FFMPEG可以把图像格式转换为YUV420P,但是现在很多视频流的格式已经是YUV420P的了或者可以被很容易的转换成YUV420P格式。
于是,我们现在计划把指导1中的SaveFrame()函数替换掉,让它直接输出我们的帧到屏幕上去。
但一开SDL_Init()函数告诉了SDL库,哪些特性我们将要用到。
当然SDL_GetError()是一个用来手工除错的函数。
创建一个显示这就创建了一个给定高度和宽度的屏幕。
下一个选项是屏幕的颜色深度――0表示使用和当前一样的深度。
FFMpeg SDK 开发手册
FFMpeg SDK 开发手册FFMpeg 中比较重要的函数以及数据结构如下:1.数据结构:(1)A VFormatContext(2)A VOutputFormat(3)A VInputFormat(4)A VCodecContext(5)A VCodec(6)A VFrame(7)A VPacket(8)A VPicture(9)A VStream2.初始化函数:(1)av_register_all()(2)avcodec_open()(3)avcodec_close()(4)av_open_input_file()(5)av_find_input_format()(6)av_find_stream_info()(7)av_close_input_file()3.音视频编解码函数:(1)avcodec_find_decoder()(2)avcodec_alloc_frame()(3)avpicture_get_size()(4)avpicture_fill()(5)img_convert()(6)avcodec_alloc_context()(7)avcodec_decode_video()(8)av_free_packet()(9)av_free()4.文件操作:(1)avnew_steam()(2)av_read_frame()(3)av_write_frame()(4)dump_format()5.其他函数:(1)avpicture_deinterlace()(2)ImgReSampleContext()以下就根据,以上数据结构及函数在ffmpeg测试代码output_example.c中出现的前后顺进行分析。
在此之前还是先谈一下ffmpeg的编译问题。
在linux下的编译比较简单,这里不多说了。
在windows下的编译可以参考以下网页:/viewthread.php?tid=1897&extra=page%3D1值得一提的是,在使用编译后的sdk进行测试时(用到ffmpeg目录下的output_example.c)编译过程中可能会有以下两个问题:1.Output_example.c用到了snprintf.h这个头文件。
ffmpeg的快速音视频开发方法
ff m p e g的快速音视频开发方法■华南理工大学 蒋志峰 在DSP平台上移植音视频编解码算法通常分为3个阶段:第1个阶段产生并评估C代码;第2个阶段优化C 代码;第3个阶段进行汇编优化[1]。
整个过程比较耗时,工作量巨大。
为减小移植工作量,可引入ff mpeg音视频开发包,在开发包基础上进行开发可以免去第一阶段工作,并减少部分第二阶段的工作。
ffmpeg是一个优秀的音视频解决方案,在此框架下可以方便、快速地进行进一步的开发。
在嵌入式硬件平台和嵌入Linux环境下,本文搭建了一种基于ffmpeg框架的音视频编解码软件开发平台,可供算法改进、性能测试,使得视频编解码算法的优化改进得以在一个高起点上快速进行。
本文分别介绍了平台搭建步骤(包括U2Boot、Linux、ffmpeg的移植)和基于ff mpeg开发的要点。
1 ffmpeg简介ffmpeg是一个集录制、转换、音/视频编解码功能为一体的、完整的开源解决方案。
ff mpeg的开发基于Linux 操作系统,也可在大多数操作系统中编译和使用。
ffmpeg 支持MPEG、DivX、MPEG4、AC3、DV、FLV等40多种编码,AVI、MPEG、O GG、Matroska、ASF等90多种解码; TCPMP、VLC、MPlayer等开源播放器都用到了ff mpeg。
它能够快速实现音视频格式转换,也能从音视频源获取数据并将其保存。
在捕获视频数据时可以设置捕获设备和视频输入标准(包括N TSC、PAL及SECAM),对于DV1394还可设置视频捕获通道。
ffmpeg使用video4linux架构的视频源,以及其他任何开源系统的音频源。
2 建立嵌入式Linux开发平台2.1 bootloader移植U2Boot是一个著名的开放源码项目,支持ARM、PowerPC等多种架构的处理器,也支持Linux、NetBSD和VxWorks等多种操作系统。
U2Boot是用于初始化目标板硬件,为嵌入式操作系统提供目标板硬件配置信息,完成嵌入式操作系统装载、引导和运行的固件程序。
FFMPEG手册
FFMPEG手册FFMPEG 编译使用msys+mingw,编译成可以供vc调用的静态库FFMPEG功能1.视频音频格式转换Ffmpeg能使用任何支持的格式和协议作为输入:*比如你可以输入YUV文件:ffmpeg -i /tmp/test%d.Y /tmp/out.mpg它将要使用如下文件:/tmp/test0.Y, /tmp/test0.U, /tmp/test0.V,/tmp/test1.Y, /tmp/test1.U, /tmp/test1.V,等等…*你能输入原始的YUV420P文件:ffmpeg -i /tmp/test.yuv /tmp/out.avi原始的YUV420P文件包含原始的YUV极性,每帧以Y平面开始,跟随U和V平面,它们是Y平面水平垂直的一半分辨率*你能输出原始的YUV420P文件ffmpeg -i mydivx.avi -o hugefile.yuv*你能设置几个输入文件和输出文件ffmpeg -i /tmp/a.wav -s 640x480 -i /tmp/a.yuv /tmp/a.mpg上面的命令行转换音频文件a.wav和原始的YUV 视频文件a.yuv到mpeg文件a.mpeg*你也能同时转换音频和视频ffmpeg -i /tmp/a.wav -ar 22050 /tmp/a.mp2上面的命令行转换a.wav的采样率到22050HZ并编码为mpeg音频*你也能同时编码到几种格式并且在输入流和输出流之间建立映射ffmpeg -i /tmp/a.wav -ab 64 /tmp/a.mp2 -ab 128 /tmp/b.mp2 -map 0:0 -map 0:0上面的命令行转换一个64Kbits 的a.wav到128kbits的a.mp2 ‘-map file:index’在输出流的顺序上定义了那一路输入流是用于每一个输出流的,转码解密的VOB:ffmpeg -i snatch_1.vob -f avi -vcodec mpeg4 -b 800 -g 300 -bf 2 -acodec mp3 -ab 128 snatch.avi上面的命令行将vob的文件转化成avi文件,mpeg4的视频和mp3的音频。
ffmpeg开发指南
ffmpeg开发指南FFmpeg 是一个开源的跨平台音视频处理工具,它提供了一套丰富的功能和库,可以用来处理音视频文件、转码、剪切、合并等等。
本文将为你介绍如何开始 FFmpeg 的开发,并提供一些常用的功能示例。
第一步:安装 FFmpeg第二步:了解 FFmpeg 的基本结构在开始开发之前,你需要了解一些 FFmpeg 的基本结构和术语。
FFmpeg 是一个由多个库组成的多媒体处理框架,其中最核心的库是libavformat、libavcodec、libavfilter 和 libswscale。
libavformat 用于处理音视频的输入和输出,libavcodec 用于进行音视频编解码,libavfilter 用于实现音视频滤镜效果,libswscale 用于进行图片缩放和格式转换。
第三步:编写第一个 FFmpeg 程序下面是一个简单的使用 FFmpeg 进行音频解码并保存为文件的示例程序:```c#include <stdio.h>#include <libavformat/avformat.h>#include <libavcodec/avcodec.h>int main(int argc, char *argv[])av_register_all(;AVFormatContext *formatContext = NULL;if (avformat_open_input(&formatContext, argv[1], NULL, NULL) != 0)printf("无法打开输入文件\n");return -1;}if (avformat_find_stream_info(formatContext, NULL) < 0) printf("无法获取流信息\n");return -1;}int audioStreamIndex = -1;for (int i = 0; i < formatContext->nb_streams; i++)if (formatContext->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)audioStreamIndex = i;break;}}if (audioStreamIndex == -1)printf("找不到音频流\n");return -1;}AVCodecParameters *audioCodecParameters = formatContext->streams[audioStreamIndex]->codecpar;AVCodec *audioCodec =avcodec_find_decoder(audioCodecParameters->codec_id);if (audioCodec == NULL)printf("找不到解码器\n");return -1;}AVCodecContext *audioCodecContext =avcodec_alloc_context3(audioCodec);if (avcodec_parameters_to_context(audioCodecContext, audioCodecParameters) != 0)printf("无法初始化解码器上下文\n");return -1;}if (avcodec_open2(audioCodecContext, audioCodec, NULL) != 0) printf("无法打开解码器\n");}AVPacket *packet = av_packet_alloc(;AVFrame *frame = av_frame_alloc(;while (av_read_frame(formatContext, packet) >= 0)if (packet->stream_index == audioStreamIndex)if (avcodec_send_packet(audioCodecContext, packet) != 0) printf("解码失败\n");break;}while (avcodec_receive_frame(audioCodecContext, frame) == 0) //在这里可以对音频数据进行处理,比如保存为文件}}av_packet_unref(packet);}av_frame_free(&frame);av_packet_free(&packet);avformat_close_input(&formatContext);```上述程序使用 FFmpeg 解码指定音频文件,并将解码后的音频数据进行处理。
ffmpeg go语言示例-概述说明以及解释
ffmpeg go语言示例-概述说明以及解释1.引言1.1 概述概述ffmpeg是一款跨平台的开源多媒体处理工具,能够对音视频文件进行解码、编码、转码等操作。
它支持多种格式的音视频文件,包括常见的MP4、AVI、FLV等,也能够处理各种编码方式,如H.264、AAC等。
ffmpeg 以其高效稳定的性能和丰富的功能,成为了许多多媒体应用开发中的重要工具。
而go语言作为一种现代化的编程语言,具有简洁明了的语法和高效的性能。
它的并发模型和垃圾回收机制等特性,使得开发者能够轻松地编写出高性能的应用程序。
go语言在网络编程、分布式系统、云计算等领域有着广泛的应用,被许多开发者称赞为一门非常实用的语言。
本文将探讨ffmpeg与go语言的结合,介绍如何使用go语言调用ffmpeg的API,实现对音视频文件的处理。
通过这种结合,我们能够充分发挥ffmpeg和go语言的优势,提供高效稳定的音视频处理功能,并且能够利用go语言的并发特性,实现高性能的多媒体应用。
接下来的章节将分别介绍ffmpeg和go语言的基本概念和特点,然后详细说明如何使用go语言调用ffmpeg的API进行音视频处理。
同时,我们还将探讨ffmpeg与go语言结合的一些实际应用场景,并对未来的发展进行展望。
通过阅读本文,读者将了解到ffmpeg和go语言的基本原理和特点,了解如何使用go语言调用ffmpeg的API进行音视频处理,以及掌握一些实际应用场景。
通过这些内容的学习,读者可以更好地理解ffmpeg和go语言的优势,并能够应用到自己的项目中,提高开发效率和应用性能。
希望本文能够对读者有所启发,为大家在多媒体应用开发和go语言学习中提供一定的帮助。
在接下来的章节中,我们将深入探讨ffmpeg与go语言的结合,带领读者一起进入多媒体应用开发的世界。
在文章结构部分,将会对整篇文章的组织方式进行介绍。
首先,本文将分为引言、正文和结论三个主要部分。
引言部分(Section 1)将主要进行一些基础的概述,包括对文章的总体介绍(1.1 概述)、文章的组织架构(1.2 文章结构)以及文章写作的目的(1.3 目的)。
FFMPEG开发指南
FFMPEG开发指南FFMPEG是一款开放源代码的音视频处理工具,拥有许多功能强大的命令行工具,可以对音视频进行解码、编码、转码、剪辑等操作。
本文将为您提供FFMPEG开发的指南,以帮助您快速入门和开发自己的音视频处理应用。
1.学习FFMPEG基础知识要开始FFMPEG的开发,首先需要了解一些基础知识。
您可以通过阅读FFMPEG的官方文档和源代码来了解其架构、命令行工具的使用和常用的编解码器等等。
另外,还可以参考网上的教程和书籍来学习。
2.设置FFMPEG的开发环境3.使用FFMPEG的库文件在开发中,您可以使用FFMPEG的库文件来实现您的功能。
FFMPEG的库文件提供了一些API和函数,可以帮助您进行音视频的解码、编码、转码等操作。
您可以通过包含相应的头文件和链接FFMPEG的库文件来使用这些功能。
4.编写FFMPEG的应用程序一旦设置好了开发环境并熟悉了FFMPEG的库文件,您可以开始编写自己的FFMPEG应用程序了。
在这个过程中,您可以使用FFMPEG的API和函数来实现您的需求。
例如,您可以使用AVFormatContext和AVCodecContext来进行音视频的解码和编码,使用AVFilterGraph来进行滤波处理,使用AVPacket和AVFrame来处理音视频的数据等等。
5.调试和测试在开发过程中,您可能会遇到一些问题和bug。
将FFMPEG库集成到您的应用程序中可能会带来一些困难。
因此,及时调试和测试是非常重要的。
您可以使用断点和调试工具来跟踪代码的执行,并使用各种测试数据来验证您的应用程序的正确性。
6.优化和性能调整当您的应用程序基本完成后,您可能还需要进行一些优化和性能调整。
FFMPEG的处理过程可能消耗较多的计算资源,因此应该尽可能地优化您的代码和算法,以提高性能和效率。
7.文档和交流在开发过程中,您可能会遇到一些问题和困惑。
在这种情况下,您可以参考FFMPEG的官方文档和论坛,以获取帮助和解决问题。
ffmpeg(executable 参数
ffmpeg是一个开源的多媒体处理工具,具有强大的音视瓶处理能力,可用于录制、转换和流式传输音视瓶数据。
在使用ffmpeg时,可以通过设置executable参数来指定ffmpeg可执行文件的路径,以便在命令行中直接调用ffmpeg命令。
下面将介绍关于ffmpeg的executable参数的相关内容。
1. 什么是executable参数?executable参数是ffmpeg命令中的一个可选参数,用于指定ffmpeg可执行文件的路径。
在某些情况下,用户可能希望使用特定版本的ffmpeg,或者在不同的操作系统中使用不同的ffmpeg版本,这时就可以通过executable参数来指定需要使用的ffmpeg可执行文件的路径。
2. 如何在ffmpeg命令中使用executable参数?在使用ffmpeg命令时,可以通过以下方式使用executable参数:```ffmpeg -executable /path/to/ffmpeg```其中,/path/to/ffmpeg为指定的ffmpeg可执行文件的路径。
通过设置此参数,可以确保在命令行中使用指定路径的ffmpeg命令。
3. 为什么需要使用executable参数?在实际的音视瓶处理任务中,可能会遇到需要使用特定版本的ffmpeg 或者在不同的操作系统中使用不同的ffmpeg版本的情况。
此时,通过设置executable参数可以灵活地指定需要使用的ffmpeg可执行文件的路径,以满足不同的需求。
4. executable参数的使用注意事项在使用executable参数时,需要注意以下几点:- 确保指定的ffmpeg可执行文件路径是正确的,否则将无法正常调用ffmpeg命令。
- 一般情况下,不需要频繁地使用executable参数,只有在确实需要指定特定版本的ffmpeg或在不同的操作系统中使用不同的ffmpeg 版本时才需要使用该参数。
5. 其他相关参数除了executable参数外,ffmpeg还有许多其他参数可供使用,例如输入文件参数、输出文件参数、编解码器参数等。
FFmpeg教程(超级详细版)
FFmpeg教程(超级详细版)一、参考资料FFmpeg命令(一)、使用filter_complex命令拼接视频FFmpeg 视频处理入门教程FFmpeg命令行转码ffmpeg 翻译文档 (ffmpeg-all 包含重要组件)FFmpeg—源码编译FFmpeg常用命令Linux上的ffmpeg完全使用指南视频和视频帧:FFMPEG 硬件解码API介绍二、安装ffmpeg、ffmpy安装ffmpeg# 更新源sudo apt update# 添加源sudo add-apt-repository ppa:kirillshkrogalev/ffmpeg-next# 安装ffmpegsudo apt-get install ffmpeg# 查看版本ffmpeg -version# 查看编码器和解码器ffmpeg -encoders安装ffmpypip install ffmpy==0.2.2 # 需要权限就添加sudo三、关键指令1.查看FFmpeg支持的编码器ffmpeg configure -encoders2.查看FFmpeg支持的解码器ffmpeg configure -decoders3.查看FFmpeg支持的通信协议ffmpeg configure -protocols4.查看FFmpeg所支持的音视频编码格式、文件封装格式与流媒体传输协议ffmpeg configure --help5.播放视频6.FFmpeg命令行工具学习(二):播放媒体文件的工具ffplay7.ffplay input.mp48.9.# 播放完自动退出ffplay -autoexit input.mp410.设置视频的屏幕高宽比ffmpeg -i input.mp4 -aspect 16:9 output.mp4通常使用的宽高比是:16:94:316:105:42:21:12:35:12:39:111.编码格式转换MPEG4编码转成H264编码ffmpeg -i input.mp4 -strict -2 -vcodec h264 output.mp4H264编码转成MPEG4编码ffmpeg -i input.mp4 -strict -2 -vcodec mpeg4 output.mp4四、视频压缩ffmpeg -i 2020.mp4 -vcodec h264 -vf scale=640:-2 -threads 4 2020_conv.mp4ffmpeg -i 1579251906.mp4 -strict -2 -vcodec h264 1579251906_output.mp4参数解释:-i 2020.mp4输入文件,源文件2020_conv.mp4输出文件,目标文件-vf scale=640:-2改变视频分辨率,缩放到640px宽,高度的-2是考虑到libx264要求高度是偶数,所以设置成-2,让软件自动计算得出一个接近等比例的偶数高-threads 44核运算其他参数:-s 1280x720设置输出文件的分辨率,w*h。
ffmpeg中文文档
ffmpeg中文文档转自:https://wanglongqi.github.io/tools/2015/02/13/ffmpegcn/1. 概要ffmpeg [global_options] {[input_file_options] -i INPUT_FILE} ... {[output_file_options] OUTPUT_FILE} ...2. 说明ffmpeg是一个非常快的视频和音频转换器,还可以抓取实时的音频/视频流。
它可以在任意的采样率之间的转换和调整视频,并同时使用高品质的多相滤波器。
ffmpeg从输入“文件”(其可以是常规文件,管道,网络流,录制装置等),由指定任意数量的读取-i选项,并写入到任意数量的输出“文件”,只需指定一个输出的文件名。
任何一个命令行中不能被解释为选项的内容都被认为是一个输出文件名。
每个输入或输出文件可以在原则上,包含任意数量的不同类型(视频/音频/字幕/附件/数据)的流。
输出文件中允许流的数量和类型是由输出格式容器限制决定的。
输入流和输出流直接的映射可以自动完成也可以用-map选项给定(见流选择章节)。
引用输入文件的选项时,则必须使用他们的索引(从0开始)。
例如:第一输入文件是0 ,第二个是1等。
类似地,一个文件中的流也通过其索引指定。
例如2:3指的是在第三个输入文件中的第四数据流。
参见流章节。
作为一般规则,选项作用于下一个指定的文件。
因此,命令的顺序是重要,你可以在命令行上多次相同的选项。
每次选项的出现都将作用于下一个输入或输出文件。
这条规则若有例外将会提前声明(例如冗余级别)。
不要混合输入和输出文件。
首先指定所有输入文件,那么所有的输出文件。
也不要混用属于不同的文件的选项。
所有选项仅适用于下一个输入或输出文件,之后选项将被重置。
设置输出文件以64千比特/秒的视频比特率:ffmpeg -i input.avi -b:V 64K -bufsize 64K output.avi要强制输出文件为24 fps的帧速率:ffmpeg -i input.avi -r 24 output.avi 要强制输入文件的帧频(仅对原始格式有效),以1 FPS读入文件,以每秒24帧的帧速率输出:ffmpeg -r 1 -i input.m2v -r 24 output.aviformat 选项可能需要指定,对于原始输入文件。
视频编解码FFMPEG
视频编解码FFMPEGffmpeg开发指南Posted on 2008-12-08 16:11 李健阅读(672) 评论(0) 编辑收藏引用所属分类: 视频解码笔记ffmpeg开发指南(使用 libavformat 和 libavcodec)Ffmpeg 中的Libavformat 和 libavcodec库是访问大多数视频文件格式的一个很好的方法。
不幸的是,在开发您自己的程序时,这套库基本上没有提供什么实际的文档可以用来作为参考(至少我没有找到任何文档),并且它的例程也并没有太多的帮助。
这种情况意味着,当我在最近某个项目中需要用到 libavformat/libavcodec 库时,需要作很多试验来搞清楚怎样使用它们。
这里是我所学习的,,希望我做的这些能够帮助一些人,以免他们重蹈我的覆辙,作同样的试验,遇到同样的错误。
你还可以从这里下载一个demo程序。
我将要公开的这部分代码需要0.4.8 版本的ffmpeg库中的 libavformat/libavcodec的支持(我正在写最新版本)。
如果您发现以后的版本与我写的程序不能兼容,请告知我。
在这个文档里,我仅仅涉及到如何从文件中读入视频流;音频流使用几乎同样的方法可以工作的很好,不过,我并没有实际使用过它们,所以,我没于办法提供任何示例代码。
或许您会觉得奇怪,为什么需要两个库文件 libavformat 和 libavcodec :许多视频文件格式(AVI就是一个最好的例子)实际上并没有明确指出应该使用哪种编码来解析音频和视频数据;它们只是定义了音频流和视频流(或者,有可能是多个音频视频流)如何被绑定在一个文件里面。
这就是为什么有时候,当你打开了一个AVI文件时,你只能听到声音,却不能看到图象,,因为你的系统没有安装合适的视频解码器。
所以, libavformat 用来处理解析视频文件并将包含在其中的流分离出来,而libavcodec 则处理原始音频和视频流的解码。
ffmpeg超详细综合教程
ffmpeg超详细综合教程本⽂的⽰例将实现:读取安卓⼿机摄像头数据并使⽤H.264编码格式实时编码保存为flv⽂件。
⽰例包含了1、编译适⽤于安卓平台的ffmpeg库2、在java中通过JNI使⽤ffmpeg3、读取安卓摄像头数据并在后台线程中使⽤ffmpeg进⾏编码的基本流程具有较强的综合性。
编译适⽤于安卓平台的ffmpeg库平时我们编译ffmpeg类库都是在x86平台下,⽽安卓⼿机属于arm平台,所以要先通过交叉编译的⽅法在x86平台下编译出可以在arm平台下使⽤的 ffmpeg类库。
Google就为我们提供了⼀套可以再Linux下完成该任务的r10e,在cygwin下使⽤。
ndk的下载安装基本是傻⽠式的,但要注意linux系统对x86和x64是分的很清楚的,不像windows那么随性,此外还需要提醒的是,在下载安装cygwin时,只需要选择binutils, gcc , gcc-mingw , gdb , make这⼏个组件。
安装完成后,在cygwin安装⽬录下点击cygwin.bat打开命令窗⼝,输⼊make -version验证是否安装成功。
做好以上的准备⼯作之后就可以正式开始ffmpeg源码的编译了。
⾸先需要修改configure⽂件,确保类库版本号不会出现在.so后缀名的后⾯,否则安卓平台⽆法识别这样的类库找到下⾯⼏句[plain]view plaincopy1. SLIBNAME_WITH_MAJOR='$(SLIBNAME).$(LIBMAJOR)'2. LIB_INSTALL_EXTRA_CMD='$$(RANLIB)"$(LIBDIR)/$(LIBNAME)"'3. SLIB_INSTALL_NAME='$(SLIBNAME_WITH_VERSION)'4. SLIB_INSTALL_LINKS='$(SLIBNAME_WITH_MAJOR)$(SLIBNAME)'修改为[plain]view plaincopy1. SLIBNAME_WITH_MAJOR='$(SLIBPREF)$(FULLNAME)-$(LIBMAJOR)$(SLIBSUF)'2. LIB_INSTALL_EXTRA_CMD='$$(RANLIB)"$(LIBDIR)/$(LIBNAME)"'3. SLIB_INSTALL_NAME='$(SLIBNAME_WITH_MAJOR)'4. SLIB_INSTALL_LINKS='$(SLIBNAME)'之后进⾏常规的configure配置,make, make install步骤即可,下⾯给出⼀个常规的脚本⽰例[plain]view plaincopy1. make clean2.3. export NDK=xxxx/android-ndk-r10e4. export PREBUILT=$NDK/toolchains/arm-linux-androideabi-4.8/prebuilt5. export PLATFORM=$NDK/platforms/android-8/arch-arm6. export PREFIX=../android_ffmpeglib7.8. ./configure --target-os=linux --prefix=$PREFIX \9. --enable-cross-compile \10. --enable-runtime-cpudetect \11. --disable-asm \12. --arch=arm \13. --cc=$PREBUILT/windows/bin/arm-linux-androideabi-gcc \14. --cross-prefix=$PREBUILT/windows/bin/arm-linux-androideabi- \15. --disable-stripping \16. --nm=$PREBUILT/windows/bin/arm-linux-androideabi-nm \17. --sysroot=$PLATFORM \18. --enable-gpl --enable-shared --disable-static --enable-small \19. --disable-ffprobe --disable-ffplay --disable-ffmpeg --disable-ffserver --disable-debug \20. --extra-cflags="-fPIC -DANDROID -D__thumb__ -mthumb -Wfatal-errors -Wno-deprecated -mfloat-abi=softfp -marm -march=armv7-a"21.22. make23. make install成功编译后,可以看到如下类库在java中通过JNI使⽤ffmpegJNI 即java本地接⼝,java native interface,它是⼀个协议, 该协议⽤来沟通Java代码和外部的本地C/C++代码, 通过该协议 Java代码可以调⽤外部的本地代码, 外部的C/C++ 代码可以调⽤Java代码。
ffmpeg开发指南
ffmpeg开发指南lsosa 2006-05-20ffmpeg 中的Libavformat 和 libavcodec库是访问大多数视频文件格式的一个很好的方法。
不幸的是,在开发您自己的程序时,这套库基本上没有提供什么实际的文档可以用来作为参考(至少我没有找到任何文档),并且它的例程也并没有太多的帮助。
这种情况意味着,当我在最近某个项目中需要用到 libavformat/libavcodec 库时,需要作很多试验来搞清楚怎样使用它们。
这里是我所学习的--希望我做的这些能够帮助一些人,以免他们重蹈我的覆辙,作同样的试验,遇到同样的错误。
你还可以从这里下载一个demo程序。
我将要公开的这部分代码需要0.4.8 版本的ffmpeg库中的 libavformat/libavcodec 的支持(我正在写最新版本)。
如果您发现以后的版本与我写的程序不能兼容,请告知我。
在这个文档里,我仅仅涉及到如何从文件中读入视频流;音频流使用几乎同样的方法可以工作的很好,不过,我并没有实际使用过它们,所以,我没于办法提供任何示例代码。
或许您会觉得奇怪,为什么需要两个库文件 libavformat 和 libavcodec :许多视频文件格式(AVI就是一个最好的例子)实际上并没有明确指出应该使用哪种编码来解析音频和视频数据;它们只是定义了音频流和视频流(或者,有可能是多个音频视频流)如何被绑定在一个文件里面。
这就是为什么有时候,当你打开了一个AVI文件时,你只能听到声音,却不能看到图象--因为你的系统没有安装合适的视频解码器。
所以, libavformat 用来处理解析视频文件并将包含在其中的流分离出来,而libavcodec 则处理原始音频和视频流的解码。
打开视频文件:首先第一件事情--让我们来看看怎样打开一个视频文件并从中得到流。
我们要做的第一件事情就是初始化libavformat/libavcodec:av_register_all();这一步注册库中含有的所有可用的文件格式和编码器,这样当打开一个文件时,它们才能够自动选择相应的文件格式和编码器。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
ffmpeg开发指南(使用 libavformat 和 libavcodec)Ffmpeg 中的Libavformat和 libavcodec库是访问大多数视频文件格式的一个很好的方法。
不幸的是,在开发您自己的程序时,这套库基本上没有提供什么实际的文档可以用来作为参考(至少我没有找到任何文档),并且它的例程也并没有太多的帮助。
这种情况意味着,当我在最近某个项目中需要用到 libavformat/libavcodec 库时,需要作很多试验来搞清楚怎样使用它们。
这里是我所学习的--希望我做的这些能够帮助一些人,以免他们重蹈我的覆辙,作同样的试验,遇到同样的错误。
你还可以从这里下载一个demo程序。
我将要公开的这部分代码需要0.4.8 版本的ffmpeg库中的 libavformat/libavcodec 的支持(我正在写最新版本)。
如果您发现以后的版本与我写的程序不能兼容,请告知我。
在这个文档里,我仅仅涉及到如何从文件中读入视频流;音频流使用几乎同样的方法可以工作的很好,不过,我并没有实际使用过它们,所以,我没于办法提供任何示例代码。
或许您会觉得奇怪,为什么需要两个库文件 libavformat 和 libavcodec :许多视频文件格式(AVI就是一个最好的例子)实际上并没有明确指出应该使用哪种编码来解析音频和视频数据;它们只是定义了音频流和视频流(或者,有可能是多个音频视频流)如何被绑定在一个文件里面。
这就是为什么有时候,当你打开了一个AVI文件时,你只能听到声音,却不能看到图象--因为你的系统没有安装合适的视频解码器。
所以, libavformat 用来处理解析视频文件并将包含在其中的流分离出来,而libavcodec 则处理原始音频和视频流的解码。
1打开视频文件:首先第一件事情--让我们来看看怎样打开一个视频文件并从中得到流。
我们要做的第一件事情就是初始化libavformat/libavcodec:av_register_all();这一步注册库中含有的所有可用的文件格式和编码器,这样当打开一个文件时,它们才能够自动选择相应的文件格式和编码器。
要注意你只需调用一次av_register_all(),所以,尽可能的在你的初始代码中使用它。
如果你愿意,你可以仅仅注册个人的文件格式和编码,不过,通常你不得不这么做却没有什么原因。
2下一步,打开文件:AVFormatContext *pFormatCtx;const char *filename="myvideo.mpg";// 打开视频文件if(av_open_input_file(&pFormatCtx, filename, NULL, 0, NULL)!=0)handle_error(); // 不能打开此文件最后三个参数描述了文件格式,缓冲区大小(size)和格式参数;我们通过简单地指明NULL或0告诉 libavformat 去自动探测文件格式并且使用默认的缓冲区大小。
请在你的程序中用合适的出错处理函数替换掉handle_error()。
3下一步,我们需要取出包含在文件中的流信息:// 取出流信息if(av_find_stream_info(pFormatCtx)<0)handle_error(); // 不能够找到流信息这一步会用有效的信息把 AVFormatContext 的流域(streams field)填满。
作为一个可调试的诊断,我们会将这些信息全盘输出到标准错误输出中,不过你在一个应用程序的产品中并不用这么做:dump_format(pFormatCtx, 0, filename, false);就像在引言中提到的那样,我们仅仅处理视频流,而不是音频流。
为了让这件事情更容易理解,我们只简单使用我们发现的第一种视频流:int i, videoStream;AVCodecContext *pCodecCtx;// 寻找第一个视频流videoStream=-1;for(i=0; i<pFormatCtx->nb_streams; i++)if(pFormatCtx->streams->codec.codec_type==CODEC_TYPE_VIDEO){videoStream=i;break;}if(videoStream==-1)handle_error(); // Didn't find a video stream// 得到视频流编码上下文的指针pCodecCtx=&pFormatCtx->streams[videoStream]->codec;好了,我们已经得到了一个指向视频流的称之为上下文的指针。
但是我们仍然需要找到真正的编码器打开它。
4 寻找视频流的解码器AVCodec *pCodec;pCodec=avcodec_find_decoder(pCodecCtx->codec_id);if(pCodec==NULL)handle_error(); // 找不到解码器// 通知解码器我们能够处理截断的bit流--ie,// bit流帧边界可以在包中if(pCodec->capabilities & CODEC_CAP_TRUNCATED)pCodecCtx->flags|=CODEC_FLAG_TRUNCATED;5打开解码器if(avcodec_open(pCodecCtx, pCodec)<0)handle_error(); // 打不开解码器(那么什么是“截断bit流”?好的,就像一会我们看到的,视频流中的数据是被分割放入包中的。
因为每个视频帧的数据的大小是可变的,那么两帧之间的边界就不一定刚好是包的边界。
这里,我们告知解码器我们可以处理bit流。
)存储在 AVCodecContext结构中的一个重要的信息就是视频帧速率。
为了允许非整数的帧速率(比如 NTSC的 29.97帧),速率以分数的形式存储,分子在pCodecCtx->frame_rate,分母在 pCodecCtx->frame_rate_base 中。
在用不同的视频文件测试库时,我注意到一些编码器(很显然ASF)似乎并不能正确的给予赋值( frame_rate_base 用1代替1000)。
下面给出修复补丁:// 加入这句话来纠正某些编码器产生的帧速错误if(pCodecCtx->frame_rate>1000 && pCodecCtx->frame_rate_base==1) pCodecCtx->frame_rate_base=1000;注意即使将来这个bug解决了,留下这几句话也并没有什么坏处。
视频不可能拥有超过1000fps的帧速。
6给视频帧分配空间以便存储解码后的图片:AVFrame *pFrame;pFrame=avcodec_alloc_frame();就这样,现在我们开始解码这些视频。
解码视频帧就像我前面提到过的,视频文件包含数个音频和视频流,并且他们各个独自被分开存储在固定大小的包里。
我们要做的就是使用libavformat依次读取这些包,过滤掉所有那些视频流中我们不感兴趣的部分,并把它们交给 libavcodec 进行解码处理。
在做这件事情时,我们要注意这样一个事实,两帧之间的边界也可以在包的中间部分。
听起来很复杂?幸运的是,我们在一个例程中封装了整个过程,它仅仅返回下一帧:7 bool GetNextFrame(AVFormatContext *pFormatCtx, AVCodecContext *pCodecCtx, int videoStream, AVFrame *pFrame){static AVPacket packet;static int bytesRemaining=0;static uint8_t *rawData;static bool fFirstTime=true;Int bytesDecoded;Int frameFinished;// 我们第一次调用时,将 packet.data 设置为NULL指明它不用释放了if(fFirstTime){fFirstTime=false;packet.data=NULL;}// 解码直到成功解码完整的一帧while(true){// 除非解码完毕,否则一直在当前包中工作while(bytesRemaining > 0){// 解码下一块数据bytesDecoded=avcodec_decode_video(pCodecCtx, pFrame,&frameFinished, rawData, bytesRemaining);if(bytesDecoded < 0) // 出错了?{fprintf(stderr, "Error while decoding frame\n");return false;}bytesRemaining-=bytesDecoded;rawData+=bytesDecoded;// 我们完成当前帧了吗?接着我们返回if(frameFinished)return true;}// 读取下一包,跳过所有不属于这个流的包do{// 释放旧的包if(packet.data!=NULL)av_free_packet(&packet);// 读取新的包if(av_read_packet(pFormatCtx, &packet)<0)goto loop_exit;} while(packet.stream_index!=videoStream);bytesRemaining=packet.size;rawData=packet.data;}loop_exit:// 解码最后一帧的余下部分bytesDecoded=avcodec_decode_video(pCodecCtx, pFrame, &frameFinished, rawData, bytesRemaining);// 释放最后一个包if(packet.data!=NULL)av_free_packet(&packet);return frameFinished!=0;}现在,我们要做的就是在一个循环中,调用 GetNextFrame () 直到它返回false。
还有一处需要注意:大多数编码器返回 YUV 420 格式的图片(一个亮度和两个色度通道,色度通道只占亮度通道空间分辨率的一半(译者注:此句原句为the chrominance channels samples at half the spatial resolution of the luminance channel))。