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. ...
- 10-09-2011 #1Just 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;
}
- 10-10-2011 #2Linux Guru
- 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
Also, please move this post/thread to the Programming / Scripting forum for help with source code issues.Code:// this is some code.
Sometimes, real fast is almost as good as real time.
Just remember, Semper Gumbi - always be flexible!


Reply With Quote