Find the answer to your Linux question:
Results 1 to 2 of 2
Hi all, I use the following codes trying to pack the raw H264 stream from hardware encoder into a mkv file. But the file I created can't be played successfully. ...
  1. #1
    Just Joined!
    Join Date
    Oct 2011
    Posts
    1

    Problem when package raw H264 video to MKV file

    Hi all,
    I use the following codes trying to pack the raw H264 stream from hardware encoder into a mkv file. But the file I created can't be played successfully. When I changed the OUTFILENAME into "test.avi" , it can be played now.(Of course the video player is ok)

    Can someone help me to find out the reason?
    //************Codes *****

    static AVOutputFormat *outfmt;
    static AVFormatContext *outcxt;
    static AVStream *video_st;
    static AVPacket pkt;
    #define OUTFILENAME "test.mkv"
    char *ofilename;

    static AVStream * add_video_stream(AVFormatContext *oc, enum CodecID codec_id)
    {
    AVStream *st;
    AVCodecContext *c;
    st = av_new_stream(outcxt, 0);
    if(!st)
    {
    printf("Fail to allocate output video stream.\n");
    return NULL;
    }

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

    /* put sample parameters */
    c->bit_rate = 400000;
    /* resolution must be a multiple of two */
    c->width = 352;
    c->height = 288;
    /* 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 = 6;
    c->time_base.num = 1;
    c->gop_size = 12; /* emit one intra frame every twelve frames at most */
    c->pix_fmt = PIX_FMT_YUV420P;
    // some formats want stream headers to be separate
    if(oc->oformat->flags & AVFMT_GLOBALHEADER)
    c->flags |= CODEC_FLAG_GLOBAL_HEADER;

    return st;

    }

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

    c = st->codec;
    if(CODEC_ID_H264 == c->codec_id)
    {
    fprintf(stderr, "codec H264\n");
    }

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

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


    int MkvInit(void)
    {
    av_register_all();
    avcodec_init();
    ofilename = OUTFILENAME;

    /*guess foramt*/
    outfmt = av_guess_format(NULL,ofilename,NULL);
    if(!outfmt)
    {
    printf("Could not deduce output format from file extension: using mkv.\n");
    return -1;
    }

    if (!outfmt)
    {
    printf("Could not find suitable output format\n");
    return -1;
    }

    outcxt = avformat_alloc_context();
    if(!outcxt)
    {
    fprintf(stderr, "Memory error outcxt\n");
    return -1;
    }

    outcxt->oformat = outfmt;
    snprintf(outcxt->filename, sizeof(outcxt->filename), "%s", ofilename);
    outcxt->oformat->video_codec = CODEC_ID_H264;

    video_st = NULL;
    video_st = add_video_stream(outcxt, CODEC_ID_H264);

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

    dump_format(outcxt, 0, ofilename,1);
    open_video(outcxt, video_st);

    if(!(outcxt->flags & AVFMT_NOFILE))
    {
    if(url_fopen(&outcxt->pb, ofilename, URL_WRONLY) < 0)
    {
    printf("Fail to open the output file %s\n", ofilename);
    exit(1);
    }
    }

    if(av_write_header(outcxt) < 0)
    {
    fprintf(stderr, "Fail to write the header of output file.\n");
    exit(1);
    }

    dump_format(outcxt, 0, ofilename,1);
    return 0;
    }


    int MkvWriteBuffer(int isKeyFrame, char *buffer, int buffer_len)
    {
    int ret;
    av_init_packet(&pkt);

    pkt.pts = AV_NOPTS_VALUE;
    pkt.dts = AV_NOPTS_VALUE;
    pkt.convergence_duration = AV_NOPTS_VALUE;

    if(isKeyFrame)
    {
    pkt.flags |= PKT_FLAG_KEY;
    }

    pkt.data = buffer;
    pkt.size = buffer_len;
    pkt.stream_index= video_st->index;

    ret = av_interleaved_write_frame(outcxt, &pkt);

    if(ret != 0)
    {
    printf("write frame error\n");
    return -1;
    }

    printf("write frame %d\n", buffer_len);
    return 0;
    }

    int MkvStop()
    {
    printf("start av_free_packet\n");
    av_free_packet(&pkt);
    printf("start av_write_trailer\n");
    av_write_trailer(outcxt);
    printf("start avcodec_close\n");
    avcodec_close(video_st->codec);
    printf("start av_freep codec\n");
    av_freep(&outcxt->streams[0]->codec);
    printf("start av_freep streams\n");
    av_freep(&outcxt->streams[0]);
    if (!(outfmt->flags & AVFMT_NOFILE))
    {
    printf("start url_fclose streams\n");
    /* close the output file */
    url_fclose(outcxt->pb);

    }

    printf("start av_free outcxt\n");
    av_free(outcxt);
    return 0;
    }

  2. #2
    Linux Guru Rubberman's Avatar
    Join Date
    Apr 2009
    Location
    I can be found either 40 miles west of Chicago, or in a galaxy far, far away.
    Posts
    8,974
    Please enclose the code in code blocks as in
    Code:
    // this is some code.
    Also, please move this post/thread to the Programming / Scripting forum for help with source code issues.
    Sometimes, real fast is almost as good as real time.
    Just remember, Semper Gumbi - always be flexible!

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
...