首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 媒体动画 > 多媒体 >

用ffmpeg封装h264流到MP4的有关问题

2013-01-11 
用ffmpeg封装h264流到MP4的问题大家好,我刚接触视频这方面,很没基础,现在项目需要把从设备获取的实时H264

用ffmpeg封装h264流到MP4的问题
大家好,我刚接触视频这方面,很没基础,现在项目需要把从设备获取的实时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;
}

主要代码就是这些了,其他都是一些库函数的调用
[解决办法]
封装成MP4后,可以播放么,如果不行的话,建议还是研究下MP4文件结构。

热点排行