[Libav-user] how to create seekable mkv using libavformat?
Jan Pohanka
xhpohanka at gmail.com
Fri Sep 21 10:24:41 CEST 2012
Hello,
I'm muxing a raw h264 stream from hadrdware encoder to mkv using
libavformat library. The resulting file is playable, but not properly
seekable I'm testing it in ffplay - moving to certains times causes the
image to disappear or break and there are these warnings:
[h264 @ 0x7f3298008500] Missing reference picture
[h264 @ 0x7f3298008500] decode_slice_header error
I think that the problem does not lie in the encoded stream, because when
I try a following sequence on the file
ffmpeg -i vtest.mkv -vcodec copy -f rawvideo vtest.h264
ffmpeg -i vtest.h264 -vcodec copy vtest2.mkv
the resulting vtest2.mkv is then seekable without any problems
Below there is simplified code that I use to save the frames. Can please
someone give me some advice how to alter it to make the resulting file
seekable?
void *write_thread_f(void *arg)
{
AVFormatContext *os;
AVOutputFormat *fmt;
AVStream *video_st;
...
os = avformat_alloc_context();
if (os == NULL)
return NULL;
fmt = av_guess_format(NULL, env->filename, NULL);
if (!fmt) {
fprintf(stderr, "Nemam vystupni format\n");
goto write_cleanup;
}
os->oformat = fmt;
strncpy(os->filename, env->filename, 128);
video_st = av_new_stream(os, 0);
if (!video_st) {
goto write_cleanup;
}
video_st->codec->codec_id = CODEC_ID_H264;
video_st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
video_st->codec->time_base.num = curr_fmt->time_base.num;
video_st->codec->time_base.den = curr_fmt->time_base.den;
video_st->codec->width = env->width;
video_st->codec->height = env->height;
video_st->codec->flags |= CODEC_FLAG_GLOBAL_HEADER;
if (avio_open(&os->pb, os->filename, URL_WRONLY) < 0) {
goto write_cleanup;
}
avformat_write_header(os, NULL);
t = 0;
while (...) {
struct buf_info *enc_buf;
AVPacket pkt;
ret = fifo_get(env->write_in_fifo, &enc_buf);
if (ret == FIFO_FLUSH)
goto write_cleanup2;
av_init_packet(&pkt);
pkt.data = enc_buf->user_addr;
pkt.size = enc_buf->bytes_used;
pkt.stream_index = video_st->index;
pkt.pts = av_rescale_q(t++, video_st->codec->time_base,
video_st->time_base);
if (enc_buf->flags & BUF_IFRAME)
pkt.flags |= AV_PKT_FLAG_KEY;
av_interleaved_write_frame(os, &pkt);
fifo_put(env->write_out_fifo, enc_buf);
}
env->recording = 0; /* end of recording */
pthread_mutex_unlock(&env->rec_lock);
write_cleanup2:
av_write_trailer(os);
avio_close(os->pb);
write_cleanup:
avformat_free_context(os);
regards
Jan
--
Tato zpráva byla vytvořena převratným poštovním klientem Opery:
http://www.opera.com/mail/
More information about the Libav-user
mailing list