用ffmpeg封装h264流到MP4的问题

kingteng 2010-08-06 10:47:22
大家好,我刚接触视频这方面,很没基础,现在项目需要把从设备获取的实时H264的流封装成MP4格式,我用的是FFMPEG这个库,现在的问题是我们的输入和输出没有被封装的痕迹,我贴一些关键的代码,大家帮忙分析一下谢谢了!!

初始化代码

av_register_all();
fmt = guess_format(NULL, outfile, NULL);
oc = av_alloc_format_context();
oc->oformat = fmt;

snprintf(oc->filename, sizeof(oc->filename), "%s", outfile);

video_st = NULL;
audio_st = NULL;

if (fmt->video_codec != CODEC_ID_NONE) {
video_st = add_video_stream(oc, fmt->video_codec);
}

if (av_set_parameters(oc, NULL) < 0) {
fprintf(stderr, "Invalid output format parameters\n");
exit(1);
}

if (video_st){
open_video(oc, video_st);
}

if (!(fmt->flags & AVFMT_NOFILE)) {
if (url_fopen(&oc->pb,outfile, URL_WRONLY) < 0) {
fprintf(stderr, "Could not open '%s'\n", outfile);
exit(1);
}
}

if(av_write_header(oc) < 0){
PRINTF("av_write_header failed\n");
return -1;
}

for(;;) {
/* compute current audio and video time */

if (audio_st)
audio_pts = (double)audio_st->pts.val * audio_st->time_base.num / audio_st->time_base.den;
else
audio_pts = 0.0;

if (video_st)
video_pts = (double)video_st->pts.val * video_st->time_base.num / video_st->time_base.den;
else
video_pts = 0.0;

/* write interleaved audio and video frames */
if (!video_st || (video_st && audio_st && audio_pts < video_pts)) {
PRINTF("write_audio_frame\n");// write_audio_frame(oc, audio_st);
} else {
write_video_frame(oc, video_st,fd,&msg,1080,720);
}


然后主要是在write_video_frame里面
static void write_video_frame(AVFormatContext *oc,AVStream *st,int fd,avs_un_msg_t *msg,\
int width,int height){
int out_size,ret;
AVCodecContext *c;
AVPacket pkt;
c = st->codec;

fill_yuv_image(picture,fd,msg,c->width,c->height);
if(write(FD1,picture->data[0],msg->extra) > 0)
PRINTF("write to FD1\n");
av_init_packet(&pkt);

//pkt.pts = msg->u.d4t[1];
pkt.flags |= PKT_FLAG_KEY;
pkt.stream_index = st->index;
pkt.data = (uint8_t *)picture->data[0];//注意这里,原样输出
pkt.size = msg->extra;//sizeof(AVPicture);

ret = av_write_frame(oc,&pkt);

//oc->oformat = oc->oformat->next;
if(ret != 0){
fprintf(stderr,"Error while writing video frame\n");
exit(1);
}
av_free_packet(&pkt);
//frame_count++;
}

fill_yuv_image函数是把我们接收到的实时数据封装到一个AVPicture结构里

static int fill_yuv_image(AVFrame *pic,int fd,avs_un_msg_t *msg,int width,int height){
int err;

bzero(extradata,MAX_AVS_UN_MSG_EXTRA);
err = avs_un_recv_msg(fd,msg);
err = avs_un_recv_msg_extra(fd,msg,extradata);

if(err > 0){
printf("recv extradata %d\n",err);
if(write(FD2,extradata,err) > 0)
PRINTF("write to FD2\n");
if(avpicture_fill((AVPicture *)pic,extradata,PIX_FMT_YUV420P,width,height) < 0){
PRINTF("avpicture_fill failed\n");
return -1;
}
}else{
PRINTF("avs_un_recv_msg_extra failed\n");
return -1;
}
return 0;
}

主要代码就是这些了,其他都是一些库函数的调用
...全文
1188 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
chucongqing 2013-01-23
  • 打赏
  • 举报
回复
没有编码,还有add_videostream 里面对于编码器你怎么设置的。 后面写入之前没有用avcodec_encode_video2 使用你的编码器对包进行编码啊
Dannyfly 2013-01-07
  • 打赏
  • 举报
回复
楼主的问题解决了没有啊? 解决了的话麻烦说一下,我也遇到了这个问题。如果能提供一段独立的Demo程序就更感谢了。
dfwinner_idxa 2010-09-09
  • 打赏
  • 举报
回复
你可以使用gpac的api
rienzi 2010-08-10
  • 打赏
  • 举报
回复
不知楼主如此封装h.264之后能否使用普通的播放器进行播放
david-yue 2010-08-10
  • 打赏
  • 举报
回复
封装成MP4后,可以播放么,如果不行的话,建议还是研究下MP4文件结构。

2,543

社区成员

发帖
与我相关
我的任务
社区描述
专题开发/技术/项目 多媒体/流媒体开发
社区管理员
  • 多媒体/流媒体开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧