Digital Video Forums

Go Back   Digital Video Forums > Other > Archive (Closed) > Video & Audio Codecs

 
 
LinkBack Thread Tools Rate Thread Display Modes
Old 6 Aug 2010, 10:45 AM   #1
Junior Member
Junior Member
 
Join Date: Aug 2010
Posts: 1
Default problem about muxing H264 raw stream into MP4 container

Hi all,
I use the library FFMPEG to mux a raw stream of H264(without Audio stream) into MP4 container,my code is below(It' long but I hope u would read it),problem is that the output always be the input whitout any change...Can anyone give me a tip?Thanks so much!
Code:
#include "avmuxer.h"
#include <sys/stat.h>
#include <fcntl.h>
/* 5 seconds stream duration
#define STREAM_DURATION   5.0
#define STREAM_FRAME_RATE 25 
#define STREAM_NB_FRAMES  ((int)(STREAM_DURATION * STREAM_FRAME_RATE))
*/
#define STREAM_PIX_FMT PIX_FMT_YUV420P 


AVFrame *picture;
uint8_t *video_outbuf;
int frame_count, video_outbuf_size;
static int firsttime = 0;
uint8_t *extradata;
int FD1,FD2;

int main(){
    const char                *outfile = "/mnt/test/outfile.mp4";
    AVOutputFormat             *fmt;
    AVFormatContext         *oc;
    AVStream                 *audio_st,*video_st;
    double                     audio_pts, video_pts;
    int                     i,fd,err;
    avs_un_msg_t              msg;
//----------------------
    unlink("/mnt/test/picture");
    if((FD1 = open("/mnt/test/picture",O_WRONLY | O_CREAT,0x777)) < 0){
        PRINTF("open FD failed\n");    
        return -1;
    }
    unlink("/mnt/test/extradata");
    if((FD2 = open("/mnt/test/extradata",O_WRONLY | O_CREAT,0x777)) < 0){
        PRINTF("open FD failed\n");    
        return -1;
    }
//----------------------
    /* initialize libavcodec, and register all codecs and formats */
    extradata = malloc(MAX_AVS_UN_MSG_EXTRA);
    unlink(outfile);
    av_register_all();


    /* auto detect the output format from the name. default is
       mpeg. */
    fmt = guess_format(NULL, outfile, NULL);
    if (!fmt) {
        printf("Could not deduce output format from file extension: using MPEG.\n");
        fmt = guess_format("mpeg", NULL, NULL);
        if (!fmt) {
            fprintf(stderr, "Could not find suitable output format\n");
            exit(1);
        }
    }
    

    oc = av_alloc_format_context();
    if (!oc) {
        fprintf(stderr, "Memory error\n");
        exit(1);
    }
    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 (fmt->audio_codec != CODEC_ID_NONE) {
        audio_st = add_audio_stream(oc, fmt->audio_codec);
    }
    */
    if (av_set_parameters(oc, NULL) < 0) {
        fprintf(stderr, "Invalid output format parameters\n");
        exit(1);
    }

    dump_format(oc, 0, outfile, 1);

    if (video_st){
        open_video(oc, video_st);
    }
    //if (audio_st)
    //    open_audio(oc, audio_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);
        }
    }

    /* write the stream header, if any */
    if(av_write_header(oc) < 0){
        PRINTF("av_write_header failed\n");    
        return -1;
    }

    if((fd = avs_un_connect("/tmp/videosvr.sock-0")) < 0){
        PRINTF("avs_un_connect failed\n");    
        return -1;
    }

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

again:
    err = avs_un_recv_msg(fd,&msg);
    if(err == -1 && msg.result != MF_OK){
        PRINTF("videosvr is not ready\n");
        sleep(1);
        goto again;
    }

    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;
 /*
         
        if ((!audio_st || audio_pts >= STREAM_DURATION) &&
            (!video_st || video_pts >= STREAM_DURATION))
            break;
*/
        /* 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);
        }
        
    }

    /* close each codec */
    if (video_st)
        close_video(oc, video_st);
    if (audio_st)
        ;//close_audio(oc, audio_st);

    /* write the trailer, if any */
    av_write_trailer(oc);

    /* free the streams */
    for(i = 0; i < oc->nb_streams; i++) {
        av_freep(&oc->streams[i]->codec);
        av_freep(&oc->streams[i]);
    }


    /* free the stream */
    av_free(oc);
    free(extradata);

    return 0;
}


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++;
}

static AVStream *add_video_stream(AVFormatContext *oc, int codec_id){
    AVCodecContext *c;
    AVStream *st;

    st = av_new_stream(oc, 0);
    if (!st) {
        fprintf(stderr, "Could not alloc stream\n");
        exit(1);
    }

    c = st->codec;
    c->codec_id = codec_id;
    c->codec_type = CODEC_TYPE_VIDEO;

    /* put sample parameters */
    c->bit_rate = 4000000;
    /* resolution must be a multiple of two */
    c->width = 1080;
    c->height = 720;
    /* time base: this is the fundamental unit of time (in seconds) in terms
       of which frame timestamps are represented. for fixed-fps content,
       timebase should be 1/framerate and timestamp increments should be
       identically 1. */
    c->time_base.den = 90000;
    c->time_base.num = 3003;
    c->gop_size = 12; /* emit one intra frame every twelve frames at most */
    c->pix_fmt = STREAM_PIX_FMT;
    if (c->codec_id == CODEC_ID_MPEG2VIDEO) {
        /* just for testing, we also add B frames */
        c->max_b_frames = 2;
    }
    if (c->codec_id == CODEC_ID_MPEG1VIDEO){
        /* Needed to avoid using macroblocks in which some coeffs overflow.
           This does not happen with normal video, it just happens here as
           the motion of the chroma plane does not match the luma plane. */
        c->mb_decision=2;
    }
    // some formats want stream headers to be separate
    if(!strcmp(oc->oformat->name, "mp4") || !strcmp(oc->oformat->name, "mov") || !strcmp(oc->oformat->name, "3gp"))
        c->flags |= CODEC_FLAG_GLOBAL_HEADER;

    return st;
}

static void open_video(AVFormatContext *oc, AVStream *st){
    AVCodec *codec;
    AVCodecContext *c;

    c = st->codec;

    /* find the video encoder */
    codec = avcodec_find_encoder(c->codec_id);
    if (!codec) {
        fprintf(stderr, "codec not found\n");
        exit(1);
    }

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

    video_outbuf = NULL;
    

    /* allocate the encoded raw picture */
    picture = my_alloc_picture(c->width,c->height);
    if (!picture) {
        fprintf(stderr, "Could not allocate picture\n");
        exit(1);
    }

    
}


static void close_video(AVFormatContext *oc, AVStream *st){
    avcodec_close(st->codec);
    av_free(picture->data[0]);
    av_free(picture);
    av_free(video_outbuf);
}


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;
}


static AVFrame *my_alloc_picture(int width,int height){
    uint8_t *picture_buf;
    int size;
    AVFrame *picture;
    
    picture = avcodec_alloc_frame();
    if (!picture)
        return NULL;
/*    
    size = avpicture_get_size(PIX_FMT_YUV420P, width, height);
    picture_buf = av_malloc(size);
    if (!picture_buf) {
        av_free(picture);
        return NULL;
    }
    
    avpicture_fill((AVPicture *)picture, picture_buf,
                       PIX_FMT_YUV420P,width, height);
*/    
    return picture;

}
rpbear is offline  
 

Bookmarks


Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools
Display Modes Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On


Similar Threads
Thread Thread Starter Forum Replies Last Post
Muxing an H264 and an AC3 into an MP4 file psychosunshine MP4, MKV, MPEG-4 AVC (H.264) 2 10 Jan 2009 11:34 AM
Good MPEG4 H264 HP to MPEG-4 VISUAL H264 Converter??? Cake^^ MP4, MKV, MPEG-4 AVC (H.264) 1 15 Sep 2008 09:39 AM
Change from OGM container to AVI container degs AVI, DivX/Xvid 7 24 Oct 2003 01:48 AM
muxing problem tonyo Authoring 3 3 Oct 2003 06:31 AM
Muxing AC3 stream and .AVI!! How??? Bulldozer AVI, DivX/Xvid 8 23 Nov 2002 08:53 AM



All times are GMT +10. The time now is 01:26 AM.

Kirsch designed by Andrew & Austin


Powered by vBulletin® Version 3.8.7
Copyright ©2000 - 2017, Jelsoft Enterprises Ltd.
Search Engine Friendly URLs by vBSEO 3.6.0
Copyright © 1999 - 2011 Digital Digest

Visit DivXLand   Visit dvdloc8.com