wtvenc: produce seekable files
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
This commit is contained in:
		
							parent
							
								
									b89cd2a028
								
							
						
					
					
						commit
						a373f35272
					
				@ -79,18 +79,44 @@ typedef struct {
 | 
			
		||||
    int                 stream_id;
 | 
			
		||||
} WtvChunkEntry;
 | 
			
		||||
 | 
			
		||||
typedef struct {
 | 
			
		||||
    int64_t serial;
 | 
			
		||||
    int64_t value;
 | 
			
		||||
} WtvSyncEntry;
 | 
			
		||||
 | 
			
		||||
typedef struct {
 | 
			
		||||
    int64_t timeline_start_pos;
 | 
			
		||||
    WtvFile file[WTV_FILES];
 | 
			
		||||
    int64_t serial;         /** chunk serial number */
 | 
			
		||||
    int64_t last_chunk_pos; /** last chunk position */
 | 
			
		||||
    int64_t last_timestamp_pos; /** last timestamp chunk position */
 | 
			
		||||
    int64_t first_index_pos;    /** first index_chunk position */
 | 
			
		||||
 | 
			
		||||
    WtvChunkEntry index[MAX_NB_INDEX];
 | 
			
		||||
    int nb_index;
 | 
			
		||||
    int first_video_flag;
 | 
			
		||||
    int64_t sync_pos;
 | 
			
		||||
 | 
			
		||||
    WtvSyncEntry *st_pairs; /* (serial, timestamp) pairs */
 | 
			
		||||
    int nb_st_pairs;
 | 
			
		||||
    WtvSyncEntry *sp_pairs; /* (serial, position) pairs */
 | 
			
		||||
    int nb_sp_pairs;
 | 
			
		||||
 | 
			
		||||
    int64_t last_pts;
 | 
			
		||||
    int64_t last_serial;
 | 
			
		||||
} WtvContext;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void add_serial_pair(WtvSyncEntry ** list, int * count, int64_t serial, int64_t value)
 | 
			
		||||
{
 | 
			
		||||
    int new_count = *count + 1;
 | 
			
		||||
    WtvSyncEntry *new_list = av_realloc(*list, new_count * sizeof(WtvSyncEntry));
 | 
			
		||||
    if (!new_list)
 | 
			
		||||
        return;
 | 
			
		||||
    new_list[*count] = (WtvSyncEntry){serial, value};
 | 
			
		||||
    *list  = new_list;
 | 
			
		||||
    *count = new_count;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
typedef int WTVHeaderWriteFunc(AVIOContext *pb);
 | 
			
		||||
 | 
			
		||||
typedef struct {
 | 
			
		||||
@ -186,6 +212,9 @@ static void write_index(AVFormatContext *s)
 | 
			
		||||
    }
 | 
			
		||||
    wctx->nb_index = 0;   // reset index
 | 
			
		||||
    finish_chunk_noindex(s);
 | 
			
		||||
 | 
			
		||||
    if (!wctx->first_index_pos)
 | 
			
		||||
        wctx->first_index_pos = wctx->last_chunk_pos;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void finish_chunk(AVFormatContext *s)
 | 
			
		||||
@ -277,12 +306,14 @@ static void write_sync(AVFormatContext *s)
 | 
			
		||||
    AVIOContext *pb = s->pb;
 | 
			
		||||
    WtvContext *wctx = s->priv_data;
 | 
			
		||||
    int64_t last_chunk_pos = wctx->last_chunk_pos;
 | 
			
		||||
    wctx->sync_pos = avio_tell(pb) - wctx->timeline_start_pos;
 | 
			
		||||
 | 
			
		||||
    write_chunk_header(s, &ff_sync_guid, 0x18, 0);
 | 
			
		||||
    write_pad(pb, 24);
 | 
			
		||||
    avio_wl64(pb, wctx->first_index_pos);
 | 
			
		||||
    avio_wl64(pb, wctx->last_timestamp_pos);
 | 
			
		||||
    avio_wl64(pb, 0);
 | 
			
		||||
 | 
			
		||||
    finish_chunk(s);
 | 
			
		||||
    add_serial_pair(&wctx->sp_pairs, &wctx->nb_sp_pairs, wctx->serial, wctx->last_chunk_pos);
 | 
			
		||||
 | 
			
		||||
    wctx->last_chunk_pos = last_chunk_pos;
 | 
			
		||||
}
 | 
			
		||||
@ -317,6 +348,9 @@ static int write_header(AVFormatContext *s)
 | 
			
		||||
    int i, pad, ret;
 | 
			
		||||
    AVStream *st;
 | 
			
		||||
 | 
			
		||||
    wctx->last_chunk_pos     = -1;
 | 
			
		||||
    wctx->last_timestamp_pos = -1;
 | 
			
		||||
 | 
			
		||||
    ff_put_guid(pb, &ff_wtv_guid);
 | 
			
		||||
    ff_put_guid(pb, &sub_wtv_guid);
 | 
			
		||||
 | 
			
		||||
@ -335,6 +369,7 @@ static int write_header(AVFormatContext *s)
 | 
			
		||||
 | 
			
		||||
    pad = (1 << WTV_SECTOR_BITS) - avio_tell(pb);
 | 
			
		||||
    write_pad(pb, pad);
 | 
			
		||||
 | 
			
		||||
    wctx->timeline_start_pos = avio_tell(pb);
 | 
			
		||||
 | 
			
		||||
    wctx->serial = 1;
 | 
			
		||||
@ -381,6 +416,8 @@ static void write_timestamp(AVFormatContext *s, AVPacket *pkt)
 | 
			
		||||
    avio_wl64(pb, 0);
 | 
			
		||||
    avio_wl64(pb, enc->codec_type == AVMEDIA_TYPE_VIDEO && (pkt->flags & AV_PKT_FLAG_KEY) ? 1 : 0);
 | 
			
		||||
    avio_wl64(pb, 0);
 | 
			
		||||
 | 
			
		||||
    wctx->last_timestamp_pos = wctx->last_chunk_pos;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int write_packet(AVFormatContext *s, AVPacket *pkt)
 | 
			
		||||
@ -388,6 +425,19 @@ static int write_packet(AVFormatContext *s, AVPacket *pkt)
 | 
			
		||||
    AVIOContext *pb = s->pb;
 | 
			
		||||
    WtvContext  *wctx = s->priv_data;
 | 
			
		||||
 | 
			
		||||
    /* emit sync chunk and 'timeline.table.0.entries.Event' record every 50 frames */
 | 
			
		||||
    if (wctx->serial - (wctx->nb_sp_pairs ? wctx->sp_pairs[wctx->nb_sp_pairs - 1].serial : 0) >= 50)
 | 
			
		||||
        write_sync(s);
 | 
			
		||||
 | 
			
		||||
    /* emit 'table.0.entries.time' record every 500ms */
 | 
			
		||||
    if (pkt->pts != AV_NOPTS_VALUE && pkt->pts - (wctx->nb_st_pairs ? wctx->st_pairs[wctx->nb_st_pairs - 1].value : 0) >= 5000000)
 | 
			
		||||
        add_serial_pair(&wctx->st_pairs, &wctx->nb_st_pairs, wctx->serial, pkt->pts);
 | 
			
		||||
 | 
			
		||||
    if (pkt->pts != AV_NOPTS_VALUE && pkt->pts > wctx->last_pts) {
 | 
			
		||||
        wctx->last_pts = pkt->pts;
 | 
			
		||||
        wctx->last_serial = wctx->serial;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // write timestamp chunk
 | 
			
		||||
    write_timestamp(s, pkt);
 | 
			
		||||
 | 
			
		||||
@ -520,10 +570,24 @@ static void write_table_entries_events(AVFormatContext *s)
 | 
			
		||||
{
 | 
			
		||||
    AVIOContext *pb = s->pb;
 | 
			
		||||
    WtvContext *wctx = s->priv_data;
 | 
			
		||||
    int i;
 | 
			
		||||
    for (i = 0; i < wctx->nb_sp_pairs; i++) {
 | 
			
		||||
        avio_wl64(pb, wctx->sp_pairs[i].serial);
 | 
			
		||||
        avio_wl64(pb, wctx->sp_pairs[i].value);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
    //FIXME: output frame_nb, position pairs.
 | 
			
		||||
    //We only set the first sync_chunk position here.
 | 
			
		||||
    avio_wl64(pb, 0x2);   avio_wl64(pb, wctx->sync_pos);
 | 
			
		||||
static void write_table_entries_time(AVFormatContext *s)
 | 
			
		||||
{
 | 
			
		||||
    AVIOContext *pb = s->pb;
 | 
			
		||||
    WtvContext *wctx = s->priv_data;
 | 
			
		||||
    int i;
 | 
			
		||||
    for (i = 0; i < wctx->nb_st_pairs; i++) {
 | 
			
		||||
        avio_wl64(pb, wctx->st_pairs[i].value);
 | 
			
		||||
        avio_wl64(pb, wctx->st_pairs[i].serial);
 | 
			
		||||
    }
 | 
			
		||||
    avio_wl64(pb, wctx->last_pts);
 | 
			
		||||
    avio_wl64(pb, wctx->last_serial);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void write_tag(AVIOContext *pb, const char *key, const char *value)
 | 
			
		||||
@ -648,7 +712,7 @@ static int write_trailer(AVFormatContext *s)
 | 
			
		||||
        return -1;
 | 
			
		||||
 | 
			
		||||
    start_pos = avio_tell(pb);
 | 
			
		||||
    //FIXME: output timestamp, frame_nb pairs here.
 | 
			
		||||
    write_table_entries_time(s);
 | 
			
		||||
    if (finish_file(s, WTV_TABLE_0_ENTRIES_TIME, start_pos) < 0)
 | 
			
		||||
        return -1;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1,3 +1,3 @@
 | 
			
		||||
dcb02f245dca4597704cbfc06e7eb543 *./tests/data/lavf/lavf.wtv
 | 
			
		||||
345516d3a03fd239c62e5e7257c9f4a2 *./tests/data/lavf/lavf.wtv
 | 
			
		||||
413696 ./tests/data/lavf/lavf.wtv
 | 
			
		||||
./tests/data/lavf/lavf.wtv CRC=0xcc2dc628
 | 
			
		||||
 | 
			
		||||
@ -1,41 +1,48 @@
 | 
			
		||||
ret: 0         st: 1 flags:1 dts:-0.010907 pts:-0.010907 pos:  26344 size:   208
 | 
			
		||||
ret: 0         st:-1 flags:0  ts:-1.000000
 | 
			
		||||
ret: 0         st: 1 flags:1 dts:-0.010907 pts:-0.010907 pos:  26344 size:   208
 | 
			
		||||
ret:-1         st:-1 flags:1  ts: 1.894167
 | 
			
		||||
ret: 0         st:-1 flags:1  ts: 1.894167
 | 
			
		||||
ret: 0         st: 1 flags:1 dts: 0.694399 pts: 0.694399 pos: 294744 size:   209
 | 
			
		||||
ret: 0         st: 0 flags:0  ts: 0.788334
 | 
			
		||||
ret: 0         st: 1 flags:1 dts: 0.772766 pts: 0.772766 pos: 320800 size:   209
 | 
			
		||||
ret: 0         st: 1 flags:1 dts: 0.694399 pts: 0.694399 pos: 294744 size:   209
 | 
			
		||||
ret: 0         st: 0 flags:1  ts:-0.317499
 | 
			
		||||
ret: 0         st: 1 flags:1 dts:-0.010907 pts:-0.010907 pos:  26344 size:   208
 | 
			
		||||
ret:-1         st: 1 flags:0  ts: 2.576668
 | 
			
		||||
ret:-1         st: 1 flags:1  ts: 1.470835
 | 
			
		||||
ret: 0         st: 1 flags:1  ts: 1.470835
 | 
			
		||||
ret: 0         st: 1 flags:1 dts: 0.694399 pts: 0.694399 pos: 294744 size:   209
 | 
			
		||||
ret: 0         st:-1 flags:0  ts: 0.365002
 | 
			
		||||
ret: 0         st: 1 flags:1 dts: 0.380930 pts: 0.380930 pos: 167000 size:   209
 | 
			
		||||
ret: 0         st: 1 flags:1 dts:-0.010907 pts:-0.010907 pos:  26344 size:   208
 | 
			
		||||
ret: 0         st:-1 flags:1  ts:-0.740831
 | 
			
		||||
ret: 0         st: 1 flags:1 dts:-0.010907 pts:-0.010907 pos:  26344 size:   208
 | 
			
		||||
ret:-1         st: 0 flags:0  ts: 2.153336
 | 
			
		||||
ret:-1         st: 0 flags:1  ts: 1.047503
 | 
			
		||||
ret: 0         st: 0 flags:1  ts: 1.047503
 | 
			
		||||
ret: 0         st: 1 flags:1 dts: 0.694399 pts: 0.694399 pos: 294744 size:   209
 | 
			
		||||
ret: 0         st: 1 flags:0  ts:-0.058330
 | 
			
		||||
ret: 0         st: 1 flags:1 dts:-0.010907 pts:-0.010907 pos:  26344 size:   208
 | 
			
		||||
ret:-1         st: 1 flags:1  ts: 2.835837
 | 
			
		||||
ret: 0         st: 1 flags:1  ts: 2.835837
 | 
			
		||||
ret: 0         st: 1 flags:1 dts: 0.694399 pts: 0.694399 pos: 294744 size:   209
 | 
			
		||||
ret:-1         st:-1 flags:0  ts: 1.730004
 | 
			
		||||
ret: 0         st:-1 flags:1  ts: 0.624171
 | 
			
		||||
ret: 0         st: 1 flags:1 dts: 0.616032 pts: 0.616032 pos: 266144 size:   209
 | 
			
		||||
ret: 0         st: 1 flags:1 dts:-0.010907 pts:-0.010907 pos:  26344 size:   208
 | 
			
		||||
ret: 0         st: 0 flags:0  ts:-0.481662
 | 
			
		||||
ret: 0         st: 1 flags:1 dts:-0.010907 pts:-0.010907 pos:  26344 size:   208
 | 
			
		||||
ret:-1         st: 0 flags:1  ts: 2.412505
 | 
			
		||||
ret: 0         st: 0 flags:1  ts: 2.412505
 | 
			
		||||
ret: 0         st: 1 flags:1 dts: 0.694399 pts: 0.694399 pos: 294744 size:   209
 | 
			
		||||
ret:-1         st: 1 flags:0  ts: 1.306672
 | 
			
		||||
ret: 0         st: 1 flags:1  ts: 0.200839
 | 
			
		||||
ret: 0         st: 1 flags:1 dts: 0.224195 pts: 0.224195 pos: 112904 size:   209
 | 
			
		||||
ret: 0         st:-1 flags:0  ts:-0.904994
 | 
			
		||||
ret: 0         st: 1 flags:1 dts:-0.010907 pts:-0.010907 pos:  26344 size:   208
 | 
			
		||||
ret:-1         st:-1 flags:1  ts: 1.989173
 | 
			
		||||
ret: 0         st:-1 flags:1  ts: 1.989173
 | 
			
		||||
ret: 0         st: 1 flags:1 dts: 0.694399 pts: 0.694399 pos: 294744 size:   209
 | 
			
		||||
ret: 0         st: 0 flags:0  ts: 0.883340
 | 
			
		||||
ret: 0         st: 1 flags:1 dts: 0.903379 pts: 0.903379 pos: 357632 size:   209
 | 
			
		||||
ret: 0         st: 1 flags:1 dts: 0.694399 pts: 0.694399 pos: 294744 size:   209
 | 
			
		||||
ret: 0         st: 0 flags:1  ts:-0.222493
 | 
			
		||||
ret: 0         st: 1 flags:1 dts:-0.010907 pts:-0.010907 pos:  26344 size:   208
 | 
			
		||||
ret:-1         st: 1 flags:0  ts: 2.671674
 | 
			
		||||
ret:-1         st: 1 flags:1  ts: 1.565841
 | 
			
		||||
ret: 0         st: 1 flags:1  ts: 1.565841
 | 
			
		||||
ret: 0         st: 1 flags:1 dts: 0.694399 pts: 0.694399 pos: 294744 size:   209
 | 
			
		||||
ret: 0         st:-1 flags:0  ts: 0.460008
 | 
			
		||||
ret: 0         st: 1 flags:1 dts: 0.459297 pts: 0.459297 pos: 205328 size:   209
 | 
			
		||||
ret: 0         st: 1 flags:1 dts:-0.010907 pts:-0.010907 pos:  26344 size:   208
 | 
			
		||||
ret: 0         st:-1 flags:1  ts:-0.645825
 | 
			
		||||
ret: 0         st: 1 flags:1 dts:-0.010907 pts:-0.010907 pos:  26344 size:   208
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user