`

ffmepg_sdk yuv编解码

 
阅读更多

对yuv文件编码h264,在解码回来,使用的FFmpeg-full-SDK-3.2

 

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#include "libavcodec/avcodec.h"
#include "libavformat/avformat.h"
#include "libavutil/avutil.h"

void video_encode(const char * inputfilename , const char *outputfilename)
{
	AVCodec *codec;
	AVCodecContext *c= NULL;
	int out_size, in_size, size,outbuf_size;
	FILE *f_out,*f_in;
	AVFrame *picture;
	uint8_t *outbuf, *picture_buf;
	int frame = 0;
	codec = avcodec_find_encoder(CODEC_ID_H264);
	if (!codec){
		fprintf(stderr, "codec not found\n");
		exit(1);
	}
	c = avcodec_alloc_context();
	picture= avcodec_alloc_frame();
	/* put sample parameters */
	c->bit_rate = 400000;
	/* resolution must be a multiple of two */
	c->width = 352;
	c->height = 288;
	/* frames per second */
	c->time_base.den = 25; 
	c->time_base.num = 1;
	/* emit one intra frame every ten frames */
	c->gop_size = 10;
	c->max_b_frames=1;
	c->pix_fmt = PIX_FMT_YUV420P;
	 /* open it */
	if (avcodec_open(c, codec) < 0){
		fprintf(stderr, "could not open codec\n");
		exit(1);
	}
	f_in = fopen(inputfilename,"rb+");
	if (!f_in){
		fprintf(stderr, "could not open %s\n", inputfilename);
		exit(1);	
	}
	f_out = fopen(outputfilename, "wb+");
	if (!f_out){
		fprintf(stderr, "could not open %s\n", outputfilename);
		exit(1);
	}
	/* alloc image and output buffer */
	outbuf_size = 100000;
	outbuf = (uint8_t *)malloc(outbuf_size);
	size = c->width * c->height;
	picture_buf = (uint8_t *)malloc((size * 3) / 2);/* size for YUV 420 */

	picture->data[0] = picture_buf;
	picture->data[1] = picture->data[0] + size;
	picture->data[2] = picture->data[1] + size / 4;
	picture->linesize[0] = c->width;
	picture->linesize[1] = c->width / 2;
	picture->linesize[2] = c->width / 2;
	for (;;){
		in_size = fread(picture_buf,sizeof(char),size * 3/2,f_in); 
		picture->data[0] = picture_buf;
		out_size = avcodec_encode_video(c, outbuf, outbuf_size, picture);
		fwrite(outbuf, 1, out_size, f_out);
		if (in_size == 0)break;
		frame ++;
	}
	printf("frame=%d\n",frame);
	fclose(f_in);
	f_in = NULL;
	fclose(f_out);
	f_out = NULL;
	free(picture_buf);
	picture_buf = NULL;
	free(outbuf);
	outbuf = NULL;
	avcodec_close(c);
	av_free(c);
	c = NULL;
	av_free(picture);
	picture = NULL; 
}

int findStartCode (unsigned char *in_buf, int zeros_in_startcode)
{
	int info;
	int i;

	info = 1;
	for (i = 0; i < zeros_in_startcode; i++)
		if(in_buf[i] != 0)
			info = 0;

	if(in_buf[i] != 1)
		info = 0;
	return info;
}

int getNextNal(FILE* f_in, unsigned char* in_buf)
{
	int pos = 0;
	int startCodeFound = 0;
	int info2 = 0;
	int info3 = 0;
	while(!feof(f_in) && (in_buf[pos++]=fgetc(f_in))==0);

	while (!startCodeFound)
	{
		if (feof (f_in))
		{
			//			return -1;
			return pos-1;
		}
		in_buf[pos++] = fgetc (f_in);
		info3 = findStartCode(&in_buf[pos-4], 3);
		if(info3 != 1)
			info2 = findStartCode(&in_buf[pos-3], 2);
		startCodeFound = (info2 == 1 || info3 == 1);
	}
	fseek (f_in, -4, SEEK_CUR);
	return pos - 4;
}

void video_decode(const char * inputfilename , const char *outputfilename)
{
	FILE * f_in,*f_out;
	AVCodec *codec;
	AVCodecContext *c;
	AVFrame *picture;
	int nWrite; 
	int i,p; 
	int nalLen; 
	unsigned char* in_buf; 
	int got_picture, out_size;
	int frame = 0;
	codec = avcodec_find_decoder(CODEC_ID_H264); 
	c = avcodec_alloc_context(); 
	picture = avcodec_alloc_frame(); 
	if (avcodec_open(c, codec) < 0){
		fprintf(stderr, "could not open codec\n");
		exit(1);
	}
	f_in = fopen(inputfilename,"rb+");
	if (!f_in){
		fprintf(stderr, "could not open %s\n", inputfilename);
		exit(1);	
	}
	f_out = fopen(outputfilename, "wb+");
	if (!f_out){
		fprintf(stderr, "could not open %s\n", outputfilename);
		exit(1);
	}

	in_buf = (unsigned char*)calloc ( 100000, sizeof(char));

	while(!feof(f_in)) { 
		nalLen = getNextNal(f_in, in_buf); 
		out_size= avcodec_decode_video(c, picture, &got_picture, in_buf, nalLen); 
		if(out_size>0) 
		{ 
			for(i=0; i<c->height; i++)
				fwrite(picture->data[0] + i * picture->linesize[0], 1, c->width, f_out);
			for(i=0; i<c->height/2; i++)
				fwrite(picture->data[1] + i * picture->linesize[1], 1, c->width/2, f_out);
			for(i=0; i<c->height/2; i++)
				fwrite(picture->data[2] + i * picture->linesize[2], 1, c->width/2, f_out);			
			frame++;
		} 
	} 
	printf("frame=%d\n",frame);
	fclose(f_in); 
	fclose(f_out);
	avcodec_close(c); 
	av_free(c); 
	c = NULL; 
	av_free(picture); 
	picture = NULL; 
	free(in_buf); 
	in_buf = NULL; 

}

int main()
{
	avcodec_init(); 
	avcodec_register_all();

	//video_encode("video/14-31-01.yuv" ,"video/14-31-01_yuv_encode.264");
	//video_decode("video/14-31-01_yuv_encode.264" ,"video/14-31-01_h264_decode.yuv");

	//video_encode("video/22.yuv" ,"video/22_yuv_encode.264");
	//video_decode("video/22_yuv_encode.264" ,"video/22_h264_decode.yuv");


	//video_encode("video/flower_cif.yuv" ,"video/flower_cif_yuv_encode.264");
	//video_decode("video/flower_cif_yuv_encode.264" ,"video/flower_cif_h264_decode.yuv");

	return EXIT_SUCCESS;
}
分享到:
评论

相关推荐

    ffmpeg_full_SDK_V3.0

    FFmpeg_full_SDK_V3.0是一个专为处理视频和音频编码解码的开源软件开发工具包,主要聚焦于H264编码标准。这个压缩包包含了大量的资源,如源代码,帮助开发者理解和实现H264编码在FFmpeg中的应用。下面我们将详细探讨...

    Using_FFmpeg_with_NVIDIA_GPU_Hardware_Acceleration_v01.4.pdf

    这些硬件能力通过NVIDIA视频编解码SDK提供的APIs (NVENCODE API和NVDECODE API) 暴露出来,使得用户能够通过这些API访问NVENC和NVDEC的硬件加速能力。 ### 知识点三:FFmpeg与NVIDIA硬件加速的结合 通过将NVENC和...

    ffmpeg3.4.1 将YUV数据封装成Mp4文件

    在FFmpeg中,你可以使用C++ API来实现各种功能,包括将YUV数据封装成MP4文件。标题提到的"ffmpeg3.4.1 将YUV数据封装成Mp4文件",涉及到的关键步骤包括初始化、编码和反初始化。以下是对这些过程的详细解释: 1. **...

    使用ffmpeg sdk开发解码

    在本教程中,我们将探讨如何利用FFmpeg SDK在VC++环境中开发一个基本的视频解码器,特别关注H264视频流的解码并将其转换为YUV格式。 首先,你需要获取FFmpeg源代码并配置编译环境。FFmpeg项目在GitHub上有源代码...

    FFmpeg:YUV转H264,(内存中)H264保存flv

    对于在内存中处理数据,FFmpeg提供了一些API,比如`av_read_frame`和`avcodec_decode_video2`来解码YUV,`avcodec_encode_video2`来编码H264,以及`av_interleaved_write_frame`来封装FLV。你需要创建一个`...

    使用 ffmpeg 和 NVCodec对视频或视频流进行硬件解码_C++_代码_相关文件_下载

    使用 ffmpeg 和 NVCodec 对视频或视频流进行硬件解码 解码器 Video.mp4 -&gt; cuvid(GPU Decoder) -&gt; GPU Memory -&gt; Normialize Cuda Kernel -&gt; float* Channel based -&gt; DNN Inference 输入格式:支持的文件/USB...

    FFmpeg视频解码为逐帧数据

    在VS2008平台上使用FFmpeg SDK 3.2进行视频解码是常见的多媒体开发实践。本示例将详细介绍如何在Windows环境下利用FFmpeg SDK实现视频文件的解码并获取逐帧数据。 首先,要理解视频解码的基本流程。视频文件通常...

    Linux Qt、大华摄像机SDK模式、ffmpeg解码

    本文将深入探讨Linux系统下使用Qt库进行GUI编程,集成大华摄像机的SDK以实现设备控制,并利用ffmpeg进行视频解码的关键知识点。 首先,Qt是一个跨平台的C++图形用户界面应用程序框架,广泛应用于桌面、移动和嵌入式...

    通过ffmpeg sdk实现分割视频、生成视频截图源码

    在这个“通过ffmpeg sdk实现分割视频、生成视频截图源码”项目中,我们主要探讨如何使用FFmpeg SDK来实现两个核心功能:视频分割和视频截图。 **视频分割** 视频分割是指将一个完整的视频文件按照特定的时间段拆分...

    FFmpeg将YUV视频序列编码为视频

    FFmpeg SDK提供了一系列的API,允许开发者进行低级别的媒体操作,包括视频编码。要将YUV视频序列编码成视频文件,你需要遵循以下步骤: 1. **初始化FFmpeg库**:在使用FFmpeg之前,需要调用`av_register_all()`和`...

    ios-集成ffmpeg解码视频.zip

    4. 图像渲染:解码后的数据是YUV格式,可以使用OpenGL ES或Metal进行渲染。 四、音频解码 1. 类似视频解码,首先找到音频流,然后获取解码器。 2. 创建解码器上下文,并打开解码器。 3. 使用`avcodec_decode_audio4...

    ffmpeg H264解码 vc版本

    6. **视频显示**:解码得到的原始像素数据通常是以YUV格式存在的,如果需要在屏幕上显示,还需要将其转换为RGB格式,并且可能需要进行缩放或其他图像处理操作。可以使用`swscale`库来进行这样的颜色空间转换。 7. *...

    海康摄像头解码rtsp以及h.264为yuv的代码

    本文将深入探讨如何针对海康摄像头的RTSP协议进行解码,并将其H.264编码转换为YUV格式,以便进一步用于人脸识别等应用。 首先,让我们理解RTSP(Real-Time Streaming Protocol)协议。RTSP是一种应用层协议,用于...

    ffmpeg nvdia硬解封装GPU实现NV12-RGBA

    FFmpeg是一个强大的开源多媒体处理工具,它支持各种视频和音频格式的编码、解码、转换以及流媒体操作。在本文中,我们将深入探讨如何利用NVIDIA的硬件解码功能,通过FFmpeg实现实时流(RTSP)拉取并在GPU上进行NV12...

    Intel QSV加速FFmpeg.rar

    FFmpeg是一款强大的开源多媒体处理工具,它支持视频、音频的编码、解码、转换、流媒体等众多功能。Intel Quick Sync Video (QSV) 是Intel处理器内置的一种硬件加速技术,主要用于视频编码和解码,旨在提供高效能和低...

    ffmpeg 点播

    FFmpeg是一款强大的开源多媒体处理工具,它包含了音视频编解码、封装、转换、流媒体等功能。在"ffmpeg 点播"的项目中,我们主要关注的是如何利用FFmpeg库来实现一个点播系统,特别是在Windows环境下,结合Windows ...

    WinCE版本的H264(FFMPEG)解码程序

    FFmpeg在解码H264时,会使用其内部的libavcodec库,该库包含了多种编解码器。解码过程通常包括初始化解码器、解析H264的NAL单元(Network Abstraction Layer units)、解码这些单元并生成原始YUV像素数据,最后可能...

    大华SDK实时预览数据保存到指定文件,并指定码流

    这通常需要使用到视频编解码库,例如FFmpeg,将接收到的原始码流转码成H264或GBPS格式。 6. **资源释放**:当预览结束或不再需要保存时,记得关闭设备连接,释放占用的资源。 在实际开发中,除了以上的基本操作,...

    unity接入海康威视sdk

    FFmpeg是一个强大的开源多媒体处理框架,它包含了多种编解码库,能够处理音频和视频数据。在“ffmpeg算法支持win64位系统”这一描述中,意味着FFmpeg已经优化了对64位Windows操作系统的支持,可以在该环境下稳定运行...

    h264-to-rtmp.copy-frame

    总之,这个项目展示了如何使用FFmpeg SDK将H.264码流转换为RTMP流,涉及到了视频编码、解码、帧复制以及网络流媒体传输等多个关键领域。通过理解和实现这样的代码,开发者可以增强自己在多媒体处理和实时流媒体技术...

Global site tag (gtag.js) - Google Analytics