FFmpeg SDK开发模型之中的一个:解码器

简单介绍

本例解说了怎样使用ffmpeg SDK解码媒体文件;

參考源代码是ffmpeg 自带的apiexample.c

一、源代码
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h>

#ifdef HAVE_AV_CONFIG_H
#undef HAVE_AV_CONFIG_H
#endif

#include "libavcodec/avcodec.h"
#define INBUF_SIZE 4096

void pgm_save(unsigned char *buf,int wrap, int xsize,int ysize,char *filename)
{
? FILE *f;
? int i;

? f=fopen(filename,"w");
? fprintf(f,"P5\n%d %d\n%d\n",xsize,ysize,255);
? for(i=0;i<ysize;i++)
? fwrite(buf + i * wrap,1,xsize,f);
? fclose(f);
}

/*
?* Video decoding
?*/
void video_decode_example(const char *outfilename, const char *filename)
{
? AVCodec *codec;
? AVCodecContext *c= NULL;
? int frame, size, got_picture, len;
? FILE *f;
? AVFrame *picture;
? uint8_t inbuf[INBUF_SIZE + FF_INPUT_BUFFER_PADDING_SIZE], *inbuf_ptr;
? char buf[1024];

? uint8_t *pkt_ptr, pkt_len;

? /* set end of buffer to 0 (this ensures that no overreading happens for damaged mpeg streams) */
? memset(inbuf + INBUF_SIZE, 0, FF_INPUT_BUFFER_PADDING_SIZE);

? printf("Video decoding\n");

? /* find the mpeg1 video decoder */
? //codec = avcodec_find_decoder(CODEC_ID_H264);
? codec = avcodec_find_decoder(CODEC_ID_MPEG2VIDEO);
? if (!codec) {
? ? fprintf(stderr, "codec not found\n");
? ? exit(1);
? }

? c= avcodec_alloc_context();
? picture= avcodec_alloc_frame();

? if(codec->capabilities&CODEC_CAP_TRUNCATED)
? c->flags|= CODEC_FLAG_TRUNCATED; /* we dont send complete frames */

? /* for some codecs, such as msmpeg4 and mpeg4, width and height
? ? ?MUST be initialized there because these info are not available
? ? ?in the bitstream */

? /* open it */
? if (avcodec_open(c, codec) < 0) {
? ? fprintf(stderr, "could not open codec\n");
? ? exit(1);
? }

? /* the codec gives us the frame size, in samples */
? f = fopen(filename, "rb");
? if (!f) {
? ? fprintf(stderr, "could not open %s\n", filename);
? ? exit(1);
? }
? frame = 0;
? for(;;) {
? ? AVPacket pkt;

? ? if (av_read_frame(c, &pkt) < 0) {
? ? ? continue;
? ? }

? ? // ? ? ? ?size = fread(inbuf, 1, INBUF_SIZE, f);
? ? // ? ? ? ?if (size == 0)
? ? // ? ? ? ? ? ?break;

? ? /* NOTE1: some codecs are stream based (mpegvideo, mpegaudio)
? ? ? ?and this is the only method to use them because you cannot
? ? ? ?know the compressed data size before analysing it.

? ? ? ?BUT some other codecs (msmpeg4, mpeg4) are inherently frame
? ? ? ?based, so you must call them with all the data for one
? ? ? ?frame exactly. You must also initialize ‘width‘ and
? ? ? ?‘height‘ before initializing them. */

? ? /* NOTE2: some codecs allow the raw parameters (frame size,
? ? ? ?sample rate) to be changed at any frame. We handle this, so
? ? ? ?you should also take care of it */

? ? /* here, we use a stream based decoder (mpeg1video), so we
? ? ? ?feed decoder and see if it could decode a frame */
? ? pkt_len = pkt.size;
? ? pkt_ptr = pkt.data;

? ? // ?inbuf_ptr = inbuf;
? ? while (pkt_len > 0) {
? ? ? len = avcodec_decode_video2(c, picture, &got_picture,
? ? ? ? ? ? &pkt);
? ? ? if (len < 0) {
? ? ? ? fprintf(stderr, "Error while decoding frame %d\n", frame);
? ? ? ? exit(1);
? ? ? }
? ? ? if (got_picture) {
? ? ? ? printf("saving frame %3d\n", frame);
? ? ? ? fflush(stdout);

? ? ? ? /* the picture is allocated by the decoder. no need to
? ? ? ? ? ?free it */
? ? ? ? snprintf(buf, sizeof(buf), outfilename, frame);
? ? ? ? pgm_save(picture->data[0], picture->linesize[0],
? ? ? ? ? ? ? c->width, c->height, buf);
? ? ? ? frame++;
? ? ? }
? ? ? size -= len;
? ? ? inbuf_ptr += len;
? ? }
? ? av_free_packet(&pkt);
? }

? /* some codecs, such as MPEG, transmit the I and P frame with a
? ? ?latency of one frame. You must do the following to have a
? ? ?chance to get the last frame of the video */
? len = avcodec_decode_video2(c, picture, &got_picture,
? ? ? ? NULL);
? if (got_picture) {
? ? printf("saving last frame %3d\n", frame);
? ? fflush(stdout);

? ? /* the picture is allocated by the decoder. no need to
? ? ? ?free it */
? ? snprintf(buf, sizeof(buf), outfilename, frame);
? ? pgm_save(picture->data[0], picture->linesize[0],
? ? ? ? ? c->width, c->height, buf);
? ? frame++;
? }

? fclose(f);

? avcodec_close(c);
? av_free(c);
? av_free(picture);
? printf("\n");
}

int main(int argc, char **argv)
{
? const char *filename;

? /* must be called before using avcodec lib */
? avcodec_init();

? /* register all the codecs (you can also register only the codec
? ? ?you wish to have smaller code */
? avcodec_register_all();

? if (argc <= 1) {
? ? // ? ? ? ?audio_encode_example("/tmp/test.mp2");
? ? // ? ? ? ?audio_decode_example("/tmp/test.sw", "/tmp/test.mp2");

? ? video_encode_example("/tmp/test.mpg");
? ? filename = "/tmp/test.mpg";
? } else {
? ? filename = argv[1];
? }

? // ? ?audio_decode_example("/tmp/test.sw", filename);
? video_decode_example("/tmp/test%d.pgm", filename);

? return 0;
}

二、代码分析
01 ?avcodec_init(), 初始化libavcodec
02 ?avcodec_register_all(), 注冊全部编解码器和格式

03 ?codec = avcodec_find_decoder(CODEC_ID_MPEG2VIDEO), 查找mpeg2 video解码器
04 ?c ? ? = avcodec_alloc_context(), 分配AVCodecContext空间并初始化
05 ?picture = avcodec_alloc_frame(), 分配AVFrame的空间
06 ?avcodec_open(c, codec), ?使用codec来初始化c

07 ?FOR循环 {
? ? ? 07.1 av_read_frame(c, &pkt), 从输入文件里读取一个包
? ? ? 07.2 pkt_len = pkt.size;
? ? ? ? ? ?pkt_ptr = pkt.data;
? ? ? 07.3 while(pkt_len > 0) {
? ? ? ? ? ? ?07.3.1 avcodec_decode_video2(c, picture, &got_picture, &pkt), 解码当前包
? ? ? ? ? ? ?07.3.2 if (got_picture) {
? ? ? ? ? ? ? ? ? ? ? ?pgm_save(picture->data[0], ...), 对解码后的YUV数据进行处理;
? ? ? ? ? ? ? ? ? ? ? ?frame++;
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ?07.3.3 size -= len;
? ? ? ? ? ?}
? ? ? 07.4 av_free_packet(&pkt), 释放当前包
? ? }
08 ?len = avcodec_decode_video2(c, picture, &got_picture, NULL); 解码最后的帧;
09 ?if (got_picture) { ...}, 处理最后帧的YUV数据

10 ?avcodec_close(c);
11 ?av_free(c)
12 ?av_free(picture);

原文地址:https://www.cnblogs.com/ldxsuanfa/p/10947960.html

时间: 2024-10-28 07:35:37

FFmpeg SDK开发模型之中的一个:解码器的相关文章

FFmpeg SDK开发模型之一:解码器

简介 本例讲解了如何使用ffmpeg SDK解码媒体文件: 参考源码是ffmpeg 自带的apiexample.c 一.源代码 #include <stdlib.h> #include <stdio.h> #include <string.h> #include <math.h> #ifdef HAVE_AV_CONFIG_H #undef HAVE_AV_CONFIG_H #endif #include "libavcodec/avcodec.h

FFmpeg SDK开发模型之三:muxer

简介 使用FFmpeg SDK实现的H.264码流合成MPEG2-TS文件 一.源代码 int main(int argc, char* argv[]) { const char* input = NULL; const char* output= NULL; /* Obtain input params */ if (argc <= 1) { printf("Usage:\n"); printf("%s <input_file.264> <outpu

【FFMpeg视频开发与应用基础】四、调用FFmpeg SDK解析封装格式的视频为音频流和视频流

<FFMpeg视频开发与应用基础--使用FFMpeg工具与SDK>视频教程已经在"CSDN学院"上线,视频中包含了从0开始逐行代码实现FFMpeg视频开发的过程,欢迎观看!链接地址:FFMpeg视频开发与应用基础--使用FFMpeg工具与SDK 工程代码地址:FFmpeg_Tutorial 我们平常最常用的音视频文件通常不是单独的音频信号和视频信号,而是一个整体的文件.这个文件会在其中包含音频流和视频流,并通过某种方式进行同步播放.通常,文件的音频和视频通过某种标准格式进行

【FFMpeg视频开发与应用基础】五、调用FFMpeg SDK封装音频和视频为视频文件

<FFMpeg视频开发与应用基础--使用FFMpeg工具与SDK>视频教程已经在"CSDN学院"上线,视频中包含了从0开始逐行代码实现FFMpeg视频开发的过程,欢迎观看!链接地址:FFMpeg视频开发与应用基础--使用FFMpeg工具与SDK 工程代码地址:FFmpeg_Tutorial 音频和视频的封装过程为解封装的逆过程,即将独立的音频数据和视频数据按照容器文件所规定的格式封装为一个完整的视频文件的过程.对于大多数消费者来说,视频封装的容器是大家最为熟悉的,因为它直接

iOS开发UI篇—使用嵌套模型完成的一个简单汽车图标展示程序

iOS开发UI篇—使用嵌套模型完成的一个简单汽车图标展示程序 一.plist文件和项目结构图 说明:这是一个嵌套模型的示例 二.代码示例: YYcarsgroup.h文件代码: // // YYcarsgroup.h // 07-汽车展示(高级) // // Created by apple on 14-5-28. // Copyright (c) 2014年 itcase. All rights reserved. // #import <Foundation/Foundation.h> @

使用Jquery+EasyUI进行框架项目开发案例解说之中的一个---员工管理源代码分享

使用Jquery+EasyUI 进行框架项目开发案例解说之中的一个 员工管理源代码分享 在開始解说之前,我们先来看一下什么是Jquery EasyUI?jQuery EasyUI是一组基于jQuery的UI插件集合,而jQuery EasyUI的目标就是帮助web开发人员更轻松的打造出功能丰富而且美观的UI界面.开发人员不须要编写复杂的javascript,也不须要对css样式有深入的了解,开发人员须要了解的仅仅有一些简单的html标签.jQuery EasyUI为我们提供了大多数UI控件的使用

基于FFMPEG SDK流媒体开发1---解码媒体文件流信息

最近项目涉及到流媒体等开发,由于有过开发经验深知其难度所在,没办法只能重新拾起,最新版的SDK被改的一塌糊涂,不过大体的开发思路都是一样的,看多少书查多少资料都无用,一步一步的编写代码 才是学好的关键.. 我会把每一天的学习经过,更新到博文上,希望能给更多想学习的人带来帮助,篇尾附上工程     以及最新版本SDK. FFMPEG被大多数的人命令行来使用,其实在真正的流媒体开发中,要想灵活运用其开发流媒体应用层序,必须使用官方SDK开发  ,实际上我们市面上好多产品 都是基于FFMPEG,比如

基于FFMPEG SDK流媒体开发1---解码媒体文件流信息(转)

最近项目涉及到流媒体等开发,由于有过开发经验深知其难度所在,没办法只能重新拾起,最新版的SDK被改的一塌糊涂,不过大体的开发思路都是一样的,看多少书查多少资料都无用,一步一步的编写代码 才是学好的关键.. 我会把每一天的学习经过,更新到博文上,希望能给更多想学习的人带来帮助,篇尾附上工程     以及最新版本SDK. FFMPEG被大多数的人命令行来使用,其实在真正的流媒体开发中,要想灵活运用其开发流媒体应用层序,必须使用官方SDK开发  ,实际上我们市面上好多产品 都是基于FFMPEG,比如

暴走吧!Snapdragon SDK开发速成指南

(文/Aurora J) Qualcomm的Snapdragon处理器.它快如闪电.效率极高.擅长挑战多任务极限,而且拥有攻城狮们梦寐以求的无限潜能.它能确保您的手机集4G LTE.极速体验.长久续航于一身. Snapdragon处理器不不过CPU. 每一颗Snapdragon处理器都是一个集成了先进专业引擎的精密体系,这些引擎各司其职.协同工作,以超高效率为您带来您所钟爱的移动性能.包含超快的网页浏览速度,不间断的视频和音乐流.以及令人惊叹的3D游戏和拍照等. Snapdragon系列处理器是