ChinaFFmpeg

 找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 22332|回复: 11

[Windows] avcodec_encode_video2 崩溃

[复制链接]
发表于 2013-12-5 15:14:17 | 显示全部楼层 |阅读模式
[C++] 纯文本查看 复制代码
int CodecH264::encode(char* data, int length, char* encBuf, int &encodedLength)
{
	//only process one frame
	
	if (m_pCodecCtxEnc == NULL)
	{
		iniEncode(m_nEncodeWidth,m_nEncodeHeight);
	}
	
	int nBufLen = 0;
	static int i = 0;
	int got_packet=0;

//	av_init_packet(&packetEnc);    这种方式也不行, 所以主动new一个buf, 也不行。。。
// 	packetEnc.data = NULL;
// 	packetEnc.size = 0;

//主动new的buf
	decodebuf = new unsigned char[VIDEO_DECODE_BUFFER_SIZE];
	av_init_packet( &packetEnc );
	packetEnc.data = decodebuf;
	packetEnc.size = VIDEO_DECODE_BUFFER_SIZE;

	
	//PIX_FMT_RGB24 PIX_FMT_YUYV422
	
//将数据保存到AVFrame中, data中是YUV数
	int nRet = avpicture_fill((AVPicture*)m_pFrameEnc, (unsigned char *)data, PIX_FMT_YUV420P, m_nEncodeWidth, m_nEncodeHeight);
	
	if ( nRet )
	{
		if( 0 == avcodec_encode_video2(m_pCodecCtxEnc,&packetEnc,m_pFrameEnc,&got_packet) )
		{
			encodedLength = packetEnc.size;
			memcpy(encBuf, packetEnc.data, encodedLength);
		}
		
		m_pFrameEnc->pts = i++;
	}
	
	av_free_packet( &packetEnc );
	return 0;
}

void CodecH264::iniEncode(int width,int height)
{
	int nret = -1;

	if (m_pCodecCtxEnc == NULL)
	{
		AVCodec *pCodec = avcodec_find_decoder(AV_CODEC_ID_H264);
		m_pCodecCtxEnc = avcodec_alloc_context3(pCodec); 
		
		// put sample parameters 
		m_pCodecCtxEnc->bit_rate = 400000;
		m_pCodecCtxEnc->width = width;//pCodecCtxDec->width;
		m_pCodecCtxEnc->height = height;//pCodecCtxDec->height;
		m_pCodecCtxEnc->time_base.num = 1;
		m_pCodecCtxEnc->time_base.den = 25;
		m_pCodecCtxEnc->gop_size = 10;
		m_pCodecCtxEnc->max_b_frames = 1;
		m_pCodecCtxEnc->pix_fmt = AV_PIX_FMT_YUV420P;

		av_opt_set(m_pCodecCtxEnc->priv_data, "preset", "slow", 0);

		if (avcodec_open2(m_pCodecCtxEnc, pCodec,NULL) < 0)
		{
			resetEnCode();
		}
		m_pFrameEnc = avcodec_alloc_frame();
		if(!m_pFrameEnc)
		{
			resetEnCode();
		}
			
		m_pFrameEnc->format = m_pCodecCtxEnc->pix_fmt;
		m_pFrameEnc->width = m_pCodecCtxEnc->width;
		m_pFrameEnc->height = m_pCodecCtxEnc->height;

		av_image_alloc(m_pFrameEnc->data, m_pFrameEnc->linesize, m_pCodecCtxEnc->width, 
			m_pCodecCtxEnc->height,	m_pCodecCtxEnc->pix_fmt, 32);
	}
}


代码如上, iniEncode是OK的, 在运行到avcodec_encode_video2时出现崩溃, 崩溃现象如图所示, 请大神指教, 谢谢

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
回复

使用道具 举报

 楼主| 发表于 2013-12-6 10:19:12 | 显示全部楼层
在这里回复大家, 由于我太大意......在初始化的时候查找编码器却写成了查找解码器“AVCodec *pCodec = avcodec_find_decoder(AV_CODEC_ID_H264);”;  应该是:AVCodec *pCodec = avcodec_find_encoder(AV_CODEC_ID_H264);
回复 支持 1 反对 0

使用道具 举报

 楼主| 发表于 2013-12-5 15:21:29 | 显示全部楼层
占个首页,期待大神前来解答
回复 支持 反对

使用道具 举报

发表于 2013-12-5 15:28:09 | 显示全部楼层

  1. static void video_encode_example(const char *filename)
  2. {
  3.     AVCodec *codec;
  4.     AVCodecContext *c= NULL;
  5.     int i, out_size, size, x, y, outbuf_size;
  6.     FILE *f;
  7.     AVFrame *picture;
  8.     uint8_t *outbuf, *picture_buf;
  9.    
  10.     printf("Video encoding\n");                                                                                                                       
  11.    
  12.     /* find the mpeg1 video encoder */
  13.     codec = avcodec_find_encoder(CODEC_ID_MPEG1VIDEO);                                                                                                
  14.     if (!codec) {
  15.         fprintf(stderr, "codec not found\n");                                                                                                         
  16.         exit(1);                                                                                                                                      
  17.     }                                                                                                                                                
  18.    
  19.     c= avcodec_alloc_context();
  20.     picture= avcodec_alloc_frame();                                                                                                                  
  21.    
  22.     /* put sample parameters */                                                                                                                       
  23.     c->bit_rate = 400000;
  24.     /* resolution must be a multiple of two */                                                                                                        
  25.     c->width = 352;
  26.     c->height = 288;
  27.     /* frames per second */
  28.     c->time_base= (AVRational){1,25};
  29.     c->gop_size = 10; /* emit one intra frame every ten frames */                                                                                    
  30.     c->max_b_frames=1;
  31.     c->pix_fmt = PIX_FMT_YUV420P;                                                                                                                     
  32.    
  33.     /* open it */
  34.     if (avcodec_open(c, codec) < 0) {
  35.         fprintf(stderr, "could not open codec\n");                                                                                                   
  36.         exit(1);                                                                                                                                      
  37.     }                                                                                                                                                
  38.    
  39.     f = fopen(filename, "wb");                                                                                                                        
  40.     if (!f) {
  41.         fprintf(stderr, "could not open %s\n", filename);                                                                                             
  42.         exit(1);                                                                                                                                      
  43.     }                                                                                                                                                
  44.    
  45.     /* alloc image and output buffer */                                                                                                               
  46.     outbuf_size = 100000;
  47.     outbuf = malloc(outbuf_size);                                                                                                                     
  48.     size = c->width * c->height;
  49.     picture_buf = malloc((size * 3) / 2); /* size for YUV 420 */        
  50.     picture->data[0] = picture_buf;
  51.     picture->data[1] = picture->data[0] + size;
  52.     picture->data[2] = picture->data[1] + size / 4;
  53.     picture->linesize[0] = c->width;
  54.     picture->linesize[1] = c->width / 2;
  55.     picture->linesize[2] = c->width / 2;

  56.     /* encode 1 second of video */
  57.     for(i=0;i<25;i++) {
  58.         fflush(stdout);
  59.         /* prepare a dummy image */
  60.         /* Y */
  61.         for(y=0;y<c->height;y++) {
  62.             for(x=0;x<c->width;x++) {
  63.                 picture->data[0][y * picture->linesize[0] + x] = x + y + i * 3;
  64.             }
  65.         }

  66.         /* Cb and Cr */
  67.         for(y=0;y<c->height/2;y++) {
  68.             for(x=0;x<c->width/2;x++) {
  69.                 picture->data[1][y * picture->linesize[1] + x] = 128 + y + i * 2;
  70.                 picture->data[2][y * picture->linesize[2] + x] = 64 + x + i * 5;
  71.             }
  72.         }

  73.         /* encode the image */
  74.         out_size = avcodec_encode_video(c, outbuf, outbuf_size, picture);
  75.         printf("encoding frame %3d (size=%5d)\n", i, out_size);
  76.         fwrite(outbuf, 1, out_size, f);
  77.     }

  78.     /* get the delayed frames */
  79.     for(; out_size; i++) {
  80.         fflush(stdout);

  81.         out_size = avcodec_encode_video(c, outbuf, outbuf_size, NULL);
  82.         printf("write frame %3d (size=%5d)\n", i, out_size);
  83.         fwrite(outbuf, 1, out_size, f);
  84.     }

  85.     /* add sequence end code to have a real mpeg file */
  86.     outbuf[0] = 0x00;
  87.     outbuf[1] = 0x00;
  88.     outbuf[2] = 0x01;
  89.     outbuf[3] = 0xb7;
  90.     fwrite(outbuf, 1, 4, f);
  91.     fclose(f);
  92.     free(picture_buf);
  93.     free(outbuf);
  94.     avcodec_close(c);
  95.     av_free(c);
  96.     av_free(picture);
  97.     printf("\n");
  98. }

复制代码
回复 支持 反对

使用道具 举报

 楼主| 发表于 2013-12-5 16:48:35 | 显示全部楼层

你这是老版本里的例子吧, 对于我的代码, 能看出什么问题么?
回复 支持 反对

使用道具 举报

发表于 2013-12-5 17:22:29 | 显示全部楼层
编译例子会崩溃不?
可以试试不fill picutre看看会不会崩溃

回复 支持 反对

使用道具 举报

 楼主| 发表于 2013-12-5 19:14:45 | 显示全部楼层
T-Bagwell 发表于 2013-12-5 17:22
编译例子会崩溃不?
可以试试不fill picutre看看会不会崩溃

因为我是VC环境, 所以例子只能看看大体怎么写, 不好用例子来尝试
回复 支持 反对

使用道具 举报

发表于 2013-12-5 20:25:41 | 显示全部楼层
wangbingwf 发表于 2013-12-5 19:14
因为我是VC环境, 所以例子只能看看大体怎么写, 不好用例子来尝试

仅仅是怀疑avpicture_fill,可否不用这个直接试试
回复 支持 反对

使用道具 举报

 楼主| 发表于 2013-12-5 20:33:38 | 显示全部楼层
本帖最后由 wangbingwf 于 2013-12-5 20:35 编辑
孙悟空 发表于 2013-12-5 20:25
仅仅是怀疑avpicture_fill,可否不用这个直接试试

在网上看了一个人的写法, 但我尝试了还是一样的错误...我是WIN7 64位, 会跟这个有关么? 另外, 请问avcodec_encode_video2这个函数源码在哪个文件中,谢大师兄!
[C++] 纯文本查看 复制代码
        int CodecH264::encode(char* data, int length, char* encBuf, int &encodedLength)
{
	//only process one frame
	
	if (m_pCodecCtxEnc == NULL)
	{
		iniEncode(m_nEncodeWidth,m_nEncodeHeight);
	}
	
	static int iFrameNum = 0;
	encodedLength = 0;
//	int outbufsize=0;          //编码后的数据长度

	m_pFrameEnc->data[0] = (unsigned char* )data;
    m_pFrameEnc->data[1] = m_pFrameEnc->data[0] + m_pCodecCtxEnc->width * m_pCodecCtxEnc->height;
    m_pFrameEnc->data[2] = m_pFrameEnc->data[1] + m_pCodecCtxEnc->width * m_pCodecCtxEnc->height / 4;
	m_pFrameEnc->linesize[0] = m_pCodecCtxEnc->width;
	m_pFrameEnc->linesize[1] = m_pCodecCtxEnc->width / 2;
	m_pFrameEnc->linesize[2] = m_pCodecCtxEnc->width / 2;
	m_pFrameEnc->pts=(int64_t)iFrameNum * m_pCodecCtxEnc->time_base.den;
	//picture->quality=1;
	m_pFrameEnc->owner=m_pCodecCtxEnc;
	m_pFrameEnc->width=m_pCodecCtxEnc->width;
    m_pFrameEnc->height=m_pCodecCtxEnc->height;

	for(int i=0;i<25;i++) 
	{
		AVPacket pkt;
        av_init_packet(&pkt);
        pkt.data = NULL;
        pkt.size = 0;
		
		int got_packet=0;
		
		int ret = avcodec_encode_video2(m_pCodecCtxEnc, &pkt, m_pFrameEnc, &got_packet);
        if (ret < 0) 
			return 0;

		if (got_packet) 
		{
			memcpy(encBuf+encodedLength,pkt.data,pkt.size);
			
			encodedLength += pkt.size;
			
			iFrameNum++;
        }
		av_free_packet(&pkt);
    }

	return 0;

回复 支持 反对

使用道具 举报

发表于 2013-12-5 20:53:36 | 显示全部楼层
libavcodec/utils.c
应该是跟你得64位没关系
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|Archiver|ChinaFFmpeg

GMT+8, 2024-4-25 16:39 , Processed in 0.062467 second(s), 17 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表