目录
初始化 libavformat 和注册所有的复用器、解复用器和协议处理器。如果不调用这个函数,可以调用下面的三个函数来选择支持的格式。
• 注册复用器的函数是av_register_output_format()。
• 注册解复用器的函数是av_register_input_format()。
• 注册协议处理器的函数是ffurl_register_protocol()。
注:FFmpeg4.0 以上的版本,这个函数已经被废弃。
当使用AVFormatContext时, avformat_alloc_context()函数用来对AVFormatContext分配空间,
AVFormatContext *avFormatContext = avformat_alloc_context();//获取上下文
avformat_open_input的主要功能是打开一个文件,读取header,不会涉及打开编码器。
与之对应的是通过avformat_close_input函数关闭文件。
示例代码:
- int error;
- //打开视频地址并获取里面的内容(解封装)
- error = avformat_open_input(&avFormatContext, inputPath, NULL, NULL);
- if (error < 0) {
- LOGE("打开视频失败")
- return;
- }
读取音视频数据来获取一些相关的信息。
示例代码:
- if (avformat_find_stream_info(avFormatContext, NULL) < 0) {
- LOGE("获取内容失败")
- return;
- }
在FFmpeg中av_read_frame函数的作用是读取码流中的若干音频帧或者1帧数据。在解码视频时,每解码一个视频帧,需要先调用av_read_frame获取1帧视频的压缩数据,然后才能对该数据进行解码。
示例代码:
- while(1) {
- int ret = av_read_frame(avFormatContext, packet);
- if (ret != 0) {
- av_strerror(ret, buf, sizeof(buf));
- LOGE("--%s--\n", buf);
- av_packet_unref(packet);
- break;
- }
-
- if (ret >= 0 && packet->stream_index != mVideoStreamIdx) {
- av_packet_unref(packet);
- continue;
- }
- //省略...
- }
发送数据到ffmepg,放到解码队列中
- // 发送待解码包
- int result = avcodec_send_packet(mAvContext, packet);
将成功的解码队列中取出1个frame
示例代码:
- while (result >= 0) {
- result = avcodec_receive_frame(mAvContext, frame);
- if (result == AVERROR_EOF)
- break;
- else if (result == AVERROR(EAGAIN)) {
- result = 0;
- break;
- } else if (result < 0) {
- av_log(NULL, AV_LOG_ERROR, "Error decoding frame\n");
- av_frame_unref(frame);
- break;
- }
- // 省略...
-
- }
打开解码器
示例代码:
- // 打开解码器
- if (avcodec_open2(mAvContext, mVcodec, NULL) != 0){
- LOGE("打开失败")
- return;
- }
分配和返回一个 SwsContext。其原型如下:
struct SwsContext *sws_getContext(int srcW, int srcH,
enum AVPixelFormat srcFormat,
int dstW, int dstH,
enum AVPixelFormat dstFormat,
int flags,
SwsFilter *srcFilter,
SwsFilter *dstFilter,
const double *param);
示例代码:
- SwsContext* swsContext = sws_getContext(mAvContext->width,mAvContext->height,mAvContext->pix_fmt,
- mAvContext->width,mAvContext->height,AV_PIX_FMT_RGBA,
- SWS_BICUBIC,NULL,NULL,NULL);
处理图像数据。
其原型如下:
int sws_scale(struct SwsContext *c, const uint8_t *const srcSlice[],
const int srcStride[], int srcSliceY, int srcSliceH,
uint8_t *const dst[], const int dstStride[]);
参数:
SwsContext *c: 转换格式的上下文。
srcSlice[],:输入图像的每个颜色通道的数据指针。
srcStride[]:输入图像的每个颜色通道的跨度。.
srcSliceY:起始位置。
srcSliceH:处理多少行。
dst[]:输出图像的每个颜色通道数据指针。
dstStride[]:输出图像的每个颜色通道行字节数。
示例代码:
- //转换为rgb格式
- sws_scale(swsContext, (const uint8_t *const *) frame->data, frame->linesize, 0,
- frame->height, rgb_frame->data,
- rgb_frame->linesize);