The dirac raw bitstream contains enough framing information to make a full demuxer out of it. --- libavformat/diracdec.c | 146 ++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 143 insertions(+), 3 deletions(-)
diff --git a/libavformat/diracdec.c b/libavformat/diracdec.c index f275212..4386f5d 100644 --- a/libavformat/diracdec.c +++ b/libavformat/diracdec.c @@ -1,6 +1,6 @@ /* * RAW Dirac demuxer - * Copyright (c) 2007 Marco Gerards <[email protected]> + * Copyright (c) 2016 Luca Barbato * * This file is part of Libav. * @@ -19,9 +19,16 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include "libavcodec/dirac.h" #include "libavutil/intreadwrite.h" + #include "avformat.h" -#include "rawdec.h" +#include "internal.h" + +#define VC2_SEQUENCE_HEADER 0x00 +#define VC2_END_OF_SEQUENCE 0x10 +#define VC2_HQ_PICTURE 0xE8 +#define VC2_HEADER_SIZE (4 + 1 + 4 + 4) static int dirac_probe(AVProbeData *p) { @@ -31,4 +38,137 @@ static int dirac_probe(AVProbeData *p) return 0; } -FF_DEF_RAWVIDEO_DEMUXER(dirac, "raw Dirac", dirac_probe, NULL, AV_CODEC_ID_DIRAC) +static int parse_header(AVFormatContext *s, + uint32_t *payload_size) +{ + uint32_t start_code = avio_rl32(s->pb); + uint32_t prev_off, next_off; + int parse_code; + + if (s->pb->eof_reached) + return AVERROR_EOF; + + if (start_code != MKTAG('B', 'B', 'C', 'D')) { + av_log(NULL, AV_LOG_ERROR, "Bogus start_code %d\n", + start_code); + return AVERROR_INVALIDDATA; + } + + parse_code = avio_r8(s->pb); + next_off = avio_rb32(s->pb); + prev_off = avio_rb32(s->pb); + + *payload_size = next_off - VC2_HEADER_SIZE; + + av_log(s, AV_LOG_VERBOSE, + "packet %s next %u prev %u \n", + parse_code == VC2_SEQUENCE_HEADER ? "Sequence Header" : + parse_code == VC2_HQ_PICTURE ? "HQ Picture" : + parse_code == VC2_END_OF_SEQUENCE? "End of Sequence" : + "Unknown", + next_off, + prev_off); + + return parse_code; +} + +static int dirac_read_header(AVFormatContext *s) +{ + AVDiracSeqHeader *dsh; + AVStream *st = avformat_new_stream(s, NULL); + int64_t start = avio_tell(s->pb); + uint32_t size; + uint8_t *buf; + int ret; + + if (!st) + return AVERROR(ENOMEM); + + while ((ret = parse_header(s, &size)) != VC2_SEQUENCE_HEADER) { + if (ret < 0) + return ret; + + avio_skip(s->pb, size); + } + + if (size > INT_MAX) + return AVERROR(ENOSYS); + + if (!(buf = av_malloc(size))) + return AVERROR(ENOMEM); + + ret = avio_read(s->pb, buf, size); + + if (ret < 0) + goto fail; + + if (ret != size) { + ret = AVERROR_EOF; + goto fail; + } + + ret = av_dirac_parse_sequence_header(&dsh, buf, size, s); + if (ret < 0) + goto fail; + + st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO; + st->codecpar->codec_id = AV_CODEC_ID_DIRAC; + st->codecpar->width = dsh->width; + st->codecpar->height = dsh->height; + st->codecpar->format = dsh->pix_fmt; + st->codecpar->color_range = dsh->color_range; + st->codecpar->color_trc = dsh->color_trc; + st->codecpar->color_primaries = dsh->color_primaries; + st->codecpar->color_space = dsh->colorspace; + st->codecpar->profile = dsh->profile; + st->codecpar->level = dsh->level; + + avpriv_set_pts_info(st, 64, dsh->framerate.den, dsh->framerate.num); + + av_free(dsh); + + avio_seek(s->pb, start, SEEK_SET); + +fail: + av_free(buf); + return 0; +} + +static int next_header(AVFormatContext *s) +{ + uint32_t size = 0; + int ret = parse_header(s, &size); + + avio_skip(s->pb, size); + + return ret; +} + +static int dirac_read_packet(AVFormatContext *s, AVPacket *pkt) +{ + int64_t pos = avio_tell(s->pb); + int64_t end; + int ret; + + // TODO resync + while ((ret = next_header(s)) != VC2_HQ_PICTURE) { + if (ret < 0) + return ret; + } + + end = avio_tell(s->pb); + + avio_seek(s->pb, pos, SEEK_SET); + + return av_get_packet(s->pb, pkt, end - pos); +} + +AVInputFormat ff_dirac_demuxer = { + .name = "dirac", + .long_name = NULL_IF_CONFIG_SMALL("DRC"), + .read_probe = dirac_probe, + .read_header = dirac_read_header, + .read_packet = dirac_read_packet, + .extensions = "drc,vc2", + .raw_codec_id = AV_CODEC_ID_DIRAC, +}; -- 2.9.2 _______________________________________________ libav-devel mailing list [email protected] https://lists.libav.org/mailman/listinfo/libav-devel
