From 3a621c9d9929bcad3ae042c4c33308b4544c7cb1 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Sun, 19 Aug 2012 23:36:26 +0200 Subject: nutenc: Support writing an index The seek test improves in accuracy Fixes Ticket877 Signed-off-by: Michael Niedermayer --- libavformat/nutenc.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 54 insertions(+), 2 deletions(-) (limited to 'libavformat') diff --git a/libavformat/nutenc.c b/libavformat/nutenc.c index 97bed1e..c24a21a 100644 --- a/libavformat/nutenc.c +++ b/libavformat/nutenc.c @@ -521,6 +521,51 @@ static int write_chapter(NUTContext *nut, AVIOContext *bc, int id) return 0; } +static int write_index(NUTContext *nut, AVIOContext *bc){ + int i; + Syncpoint dummy= { .pos= 0 }; + Syncpoint *next_node[2] = { NULL }; + int64_t startpos = avio_tell(bc); + int64_t payload_size; + + put_tt(nut, nut->max_pts_tb, bc, nut->max_pts); + + ff_put_v(bc, nut->sp_count); + + for(i=0; isp_count; i++){ + av_tree_find(nut->syncpoints, &dummy, (void *) ff_nut_sp_pos_cmp, (void**)next_node); + ff_put_v(bc, (next_node[1]->pos >> 4) - (dummy.pos>>4)); + dummy.pos = next_node[1]->pos; + } + + for(i=0; iavf->nb_streams; i++){ + StreamContext *nus= &nut->stream[i]; + int64_t last_pts= -1; + int j, k; + for(j=0; jsp_count; j++){ + int flag = (nus->keyframe_pts[j] != AV_NOPTS_VALUE) ^ (j+1 == nut->sp_count); + int n = 0; + for(; jsp_count && (nus->keyframe_pts[j] != AV_NOPTS_VALUE) == flag; j++) + n++; + + ff_put_v(bc, 1 + 2*flag + 4*n); + for(k= j - n; k<=j && ksp_count; k++) { + if(nus->keyframe_pts[k] == AV_NOPTS_VALUE) + continue; + av_assert0(nus->keyframe_pts[k] > last_pts); + ff_put_v(bc, nus->keyframe_pts[k] - last_pts); + last_pts = nus->keyframe_pts[k]; + } + } + } + + payload_size = avio_tell(bc) - startpos + 8 + 4; + + avio_wb64(bc, 8 + payload_size + av_log2(payload_size) / 7 + 1 + 4*(payload_size > 4096)); + + return 0; +} + static int write_headers(AVFormatContext *avctx, AVIOContext *bc){ NUTContext *nut = avctx->priv_data; AVIOContext *dyn_bc; @@ -873,11 +918,18 @@ static int nut_write_packet(AVFormatContext *s, AVPacket *pkt){ static int nut_write_trailer(AVFormatContext *s){ NUTContext *nut= s->priv_data; - AVIOContext *bc= s->pb; - int i; + AVIOContext *bc = s->pb, *dyn_bc; + int i, ret; while(nut->header_count<3) write_headers(s, bc); + + ret = avio_open_dyn_buf(&dyn_bc); + if(ret >= 0) { + write_index(nut, dyn_bc); + put_packet(nut, bc, dyn_bc, 1, INDEX_STARTCODE); + } + avio_flush(bc); ff_nut_free_sp(nut); for(i=0; inb_streams; i++) -- cgit v1.1