From 26db9100b2fa8f14d63947edc50d5777e44c55e1 Mon Sep 17 00:00:00 2001 From: Luca Barbato Date: Tue, 9 Oct 2012 02:49:42 +0200 Subject: [PATCH 1/2] segment: support applehttp style list --- libavformat/segment.c | 85 ++++++++++++++++++++++++++++++++++++------- 1 file changed, 72 insertions(+), 13 deletions(-) diff --git a/libavformat/segment.c b/libavformat/segment.c index 8ac04e2f2e..fd5283560e 100644 --- a/libavformat/segment.c +++ b/libavformat/segment.c @@ -37,6 +37,7 @@ typedef struct { AVFormatContext *avf; char *format; /**< Set by a private option. */ char *list; /**< Set by a private option. */ + int list_type; /**< Set by a private option. */ float time; /**< Set by a private option. */ int size; /**< Set by a private option. */ int wrap; /**< Set by a private option. */ @@ -48,6 +49,11 @@ typedef struct { AVIOContext *pb; } SegmentContext; +enum { + LIST_FLAT, + LIST_HLS +}; + static int segment_mux_init(AVFormatContext *s) { SegmentContext *seg = s->priv_data; @@ -72,6 +78,36 @@ static int segment_mux_init(AVFormatContext *s) return 0; } +static int segment_hls_window(AVFormatContext *s, int last) +{ + SegmentContext *seg = s->priv_data; + int i, ret = 0; + char buf[1024]; + + if ((ret = avio_open2(&seg->pb, seg->list, AVIO_FLAG_WRITE, + &s->interrupt_callback, NULL)) < 0) + goto fail; + + avio_printf(seg->pb, "#EXTM3U\n"); + avio_printf(seg->pb, "#EXT-X-VERSION:3\n"); + avio_printf(seg->pb, "#EXT-X-TARGETDURATION:%d\n", (int)seg->time); + avio_printf(seg->pb, "#EXT-X-MEDIA-SEQUENCE:%d\n", + FFMAX(0, seg->number - seg->size)); + + for (i = FFMAX(0, seg->number - seg->size); + i < seg->number; i++) { + avio_printf(seg->pb, "#EXTINF:%d,\n", (int)seg->time); + av_get_frame_filename(buf, sizeof(buf), s->filename, i); + avio_printf(seg->pb, "%s\n", buf); + } + + if (last) + avio_printf(seg->pb, "#EXT-X-ENDLIST\n"); +fail: + avio_closep(&seg->pb); + return ret; +} + static int segment_start(AVFormatContext *s, int write_header) { SegmentContext *c = s->priv_data; @@ -152,7 +188,7 @@ static int seg_write_header(AVFormatContext *s) if (!seg->write_header_trailer) seg->individual_header_trailer = 0; - if (seg->list) + if (seg->list && seg->list_type != LIST_HLS) if ((ret = avio_open2(&seg->pb, seg->list, AVIO_FLAG_WRITE, &s->interrupt_callback, NULL)) < 0) goto fail; @@ -211,8 +247,13 @@ static int seg_write_header(AVFormatContext *s) } if (seg->list) { - avio_printf(seg->pb, "%s\n", oc->filename); - avio_flush(seg->pb); + if (seg->list_type == LIST_HLS) { + if ((ret = segment_hls_window(s, 0)) < 0) + goto fail; + } else { + avio_printf(seg->pb, "%s\n", oc->filename); + avio_flush(seg->pb); + } } fail: @@ -252,13 +293,18 @@ static int seg_write_packet(AVFormatContext *s, AVPacket *pkt) oc = seg->avf; if (seg->list) { - avio_printf(seg->pb, "%s\n", oc->filename); - avio_flush(seg->pb); - if (seg->size && !(seg->number % seg->size)) { - avio_close(seg->pb); - if ((ret = avio_open2(&seg->pb, seg->list, AVIO_FLAG_WRITE, - &s->interrupt_callback, NULL)) < 0) + if (seg->list_type == LIST_HLS) { + if ((ret = segment_hls_window(s, 0)) < 0) goto fail; + } else { + avio_printf(seg->pb, "%s\n", oc->filename); + avio_flush(seg->pb); + if (seg->size && !(seg->number % seg->size)) { + avio_closep(&seg->pb); + if ((ret = avio_open2(&seg->pb, seg->list, AVIO_FLAG_WRITE, + &s->interrupt_callback, NULL)) < 0) + goto fail; + } } } } @@ -281,15 +327,25 @@ static int seg_write_trailer(struct AVFormatContext *s) AVFormatContext *oc = seg->avf; int ret; if (!seg->write_header_trailer) { - ret = segment_end(oc, 0); + if ((ret = segment_end(oc, 0)) < 0) + goto fail; open_null_ctx(&oc->pb); - av_write_trailer(oc); + ret = av_write_trailer(oc); close_null_ctx(oc->pb); } else { ret = segment_end(oc, 1); } - if (seg->list) - avio_close(seg->pb); + + if (ret < 0) + goto fail; + + if (seg->list && seg->list_type == LIST_HLS) { + if ((ret = segment_hls_window(s, 1) < 0)) + goto fail; + } + +fail: + avio_close(seg->pb); avformat_free_context(oc); return ret; } @@ -301,6 +357,9 @@ static const AVOption options[] = { { "segment_time", "segment length in seconds", OFFSET(time), AV_OPT_TYPE_FLOAT, {.dbl = 2}, 0, FLT_MAX, E }, { "segment_list", "output the segment list", OFFSET(list), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, E }, { "segment_list_size", "maximum number of playlist entries", OFFSET(size), AV_OPT_TYPE_INT, {.i64 = 5}, 0, INT_MAX, E }, + { "segment_list_type", "segment list format", OFFSET(list_type), AV_OPT_TYPE_INT, {.i64 = LIST_FLAT}, 0, 2, E, "list_type" }, + { "flat", "plain list (default)", 0, AV_OPT_TYPE_CONST, {.i64 = LIST_FLAT}, 0, 0, E, "list_type" }, + { "hls", "Apple HTTP Live Streaming compatible", 0, AV_OPT_TYPE_CONST, {.i64 = LIST_HLS}, 0, 0, E, "list_type" }, { "segment_wrap", "number after which the index wraps", OFFSET(wrap), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, E }, { "individual_header_trailer", "write header/trailer to each segment", OFFSET(individual_header_trailer), AV_OPT_TYPE_INT, {.i64 = 1}, 0, 1, E }, { "write_header_trailer", "write a header to the first segment and a trailer to the last one", OFFSET(write_header_trailer), AV_OPT_TYPE_INT, {.i64 = 1}, 0, 1, E }, From 88058d9a994f42e4e9ed4e67baf696bbfe53128c Mon Sep 17 00:00:00 2001 From: Mashiat Sarker Shakkhar Date: Tue, 9 Oct 2012 19:38:15 +0000 Subject: [PATCH 2/2] vc1dec: Set chroma reference field from REFFIELD for 1REF field pictures Interlaced field pictures can have one or two reference pictures, signaled by NUMREF syntax element. For single reference pictures, reference picture is determined by REFFIELD syntax element. Signed-off-by: Derek Buitenhuis --- libavcodec/vc1dec.c | 1 + 1 file changed, 1 insertion(+) diff --git a/libavcodec/vc1dec.c b/libavcodec/vc1dec.c index b8237d7f8d..4127691dc1 100644 --- a/libavcodec/vc1dec.c +++ b/libavcodec/vc1dec.c @@ -794,6 +794,7 @@ static void vc1_mc_4mv_chroma(VC1Context *v, int dir) /* calculate chroma MV vector from four luma MVs */ if (!v->field_mode || (v->field_mode && !v->numref)) { valid_count = get_chroma_mv(mvx, mvy, intra, 0, &tx, &ty); + chroma_ref_type = v->reffield; if (!valid_count) { s->current_picture.f.motion_val[1][s->block_index[0] + v->blocks_off][0] = 0; s->current_picture.f.motion_val[1][s->block_index[0] + v->blocks_off][1] = 0;