FORUMS: list search recent posts

How can I pack raw H264 stream to MKV format?

COW Forums : FFmpeg

<< PREVIOUS   •   VIEW ALL   •   PRINT   •   NEXT >>
Howz Smith
How can I pack raw H264 stream to MKV format?
on Oct 9, 2011 at 8:57:27 am

Hi all,
I want to pack the H264 stream from hardware encoder to mkv format, however, the output file "test.mkv" can't be played by video player. The following is my codes. Can someone help me find the reason? By the way, if I use "test.avi" as the output filename, the avi file can be create successfully.

Thanks.

===========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 H264n");
}

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

/* open the codec */
if (avcodec_open(c, codec) < 0) {
fprintf(stderr, "could not open codecn");
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 formatn");
return -1;
}

outcxt = avformat_alloc_context();
if(!outcxt)
{
fprintf(stderr, "Memory error outcxtn");
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 parametersn");
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 %sn", 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 errorn");
return -1;
}

printf("write frame %dn", buffer_len);
return 0;
}

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

}

printf("start av_free outcxtn");
av_free(outcxt);
return 0;
}


Return to posts index

igsgk igsgk
Re: How can I pack raw H264 stream to MKV format?
on Jun 15, 2012 at 11:34:06 am

Hi Howz,

I used your codes to make avi and mkv file and both files work!!.

Sinan


Return to posts index

<< PREVIOUS   •   VIEW ALL   •   PRINT   •   NEXT >>
© 2017 CreativeCOW.net All Rights Reserved
[TOP]