ffmpeg开发指南(经典)

合集下载

ffmpeg 和 SDL 教程

ffmpeg 和 SDL 教程
// Save the frame to disk if(++i<=5) SaveFrame(pFrameRGB, pCodecCtx->width, pCodecCtx->height, i); } } // Free the packet that was allocated by av_read_frame av_free_packet(&packet); } 这个循环过程是比较简单的:av_read_frame()读取一个包并且把它保存到 AVPacket结构体中。注意我们仅仅申请了一个包的结构体 ――ffmpeg为我们申请 了内部的数据的内存并通过packet.data指针来指向它。这些数据可以在后面通过 av_free_packet()来释 放。函数avcodec_decode_video()把包转换为帧。然而当解码 一个包的时候,我们可能没有得到我们需要的关于帧的信息。因此,当我们得 到 下一帧的时候,avcodec_decode_video()为我们设置了帧结束标志frameFinished。 最后,我们使用 img_convert()函数来把帧从原始格式(pCodecCtx->pix_fmt)转 换成为RGB格式。要记住,你可以把一个 AVFrame结构体的指针转换为AVPicture 结构体的指针。最后,我们把帧和高度宽度信息传递给我们的SaveFrame函数。 关于包Packets的注释 从技术上讲一个包可以包含部分帧或者其它的数据,但是ffmpeg的解释器保证了 我们得到的包Packets包含的要么是完整的要么是多种完整的帧。 现在我们需要做的是让SaveFrame函数能把RGB信息定稿到一个PPM格式的文件 中。我们将生成一个简单的PPM格式文件,请相信,它是可以工作的。 void SaveFrame(AVFrame *pFrame, int width, int height, int iFrame) { FILE *pFile; char szFilename[32]; int y; // Open file sprintf(szFilename, "frame%d.ppm", iFrame); pFile=fopen(szFilename, "wb");

ffmpeg 编程手册

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 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过滤器开发和理解最近学习了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用户指南说明书

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 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:输出到屏幕

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 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这个头文件。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 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))。

相关文档
最新文档