/src/ffmpeg/libavformat/filmstripdec.c
Line | Count | Source |
1 | | /* |
2 | | * Adobe Filmstrip demuxer |
3 | | * Copyright (c) 2010 Peter Ross |
4 | | * |
5 | | * This file is part of FFmpeg. |
6 | | * |
7 | | * FFmpeg is free software; you can redistribute it and/or |
8 | | * modify it under the terms of the GNU Lesser General Public |
9 | | * License as published by the Free Software Foundation; either |
10 | | * version 2.1 of the License, or (at your option) any later version. |
11 | | * |
12 | | * FFmpeg is distributed in the hope that it will be useful, |
13 | | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
14 | | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
15 | | * Lesser General Public License for more details. |
16 | | * |
17 | | * You should have received a copy of the GNU Lesser General Public |
18 | | * License along with FFmpeg; if not, write to the Free Software |
19 | | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
20 | | */ |
21 | | |
22 | | /** |
23 | | * @file |
24 | | * Adobe Filmstrip demuxer |
25 | | */ |
26 | | |
27 | | #include "libavutil/intreadwrite.h" |
28 | | #include "libavutil/imgutils.h" |
29 | | #include "avformat.h" |
30 | | #include "demux.h" |
31 | | #include "internal.h" |
32 | | |
33 | 1.50k | #define RAND_TAG MKBETAG('R','a','n','d') |
34 | | |
35 | | typedef struct FilmstripDemuxContext { |
36 | | int leading; |
37 | | } FilmstripDemuxContext; |
38 | | |
39 | | static int read_header(AVFormatContext *s) |
40 | 1.54k | { |
41 | 1.54k | FilmstripDemuxContext *film = s->priv_data; |
42 | 1.54k | AVIOContext *pb = s->pb; |
43 | 1.54k | AVStream *st; |
44 | | |
45 | 1.54k | if (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL)) |
46 | 44 | return AVERROR(ENOSYS); |
47 | | |
48 | 1.50k | avio_seek(pb, avio_size(pb) - 36, SEEK_SET); |
49 | 1.50k | if (avio_rb32(pb) != RAND_TAG) { |
50 | 249 | av_log(s, AV_LOG_ERROR, "magic number not found\n"); |
51 | 249 | return AVERROR_INVALIDDATA; |
52 | 249 | } |
53 | | |
54 | 1.25k | st = avformat_new_stream(s, NULL); |
55 | 1.25k | if (!st) |
56 | 0 | return AVERROR(ENOMEM); |
57 | | |
58 | 1.25k | st->nb_frames = avio_rb32(pb); |
59 | 1.25k | if (avio_rb16(pb) != 0) { |
60 | 20 | avpriv_request_sample(s, "Unsupported packing method"); |
61 | 20 | return AVERROR_PATCHWELCOME; |
62 | 20 | } |
63 | | |
64 | 1.23k | avio_skip(pb, 2); |
65 | 1.23k | st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO; |
66 | 1.23k | st->codecpar->codec_id = AV_CODEC_ID_RAWVIDEO; |
67 | 1.23k | st->codecpar->format = AV_PIX_FMT_RGBA; |
68 | 1.23k | st->codecpar->codec_tag = 0; /* no fourcc */ |
69 | 1.23k | st->codecpar->width = avio_rb16(pb); |
70 | 1.23k | st->codecpar->height = avio_rb16(pb); |
71 | 1.23k | film->leading = avio_rb16(pb); |
72 | | |
73 | 1.23k | if (av_image_check_size(st->codecpar->width, st->codecpar->height, 0, s) < 0) |
74 | 104 | return AVERROR_INVALIDDATA; |
75 | | |
76 | 1.12k | avpriv_set_pts_info(st, 64, 1, avio_rb16(pb)); |
77 | | |
78 | 1.12k | avio_seek(pb, 0, SEEK_SET); |
79 | | |
80 | 1.12k | return 0; |
81 | 1.23k | } |
82 | | |
83 | | static int read_packet(AVFormatContext *s, |
84 | | AVPacket *pkt) |
85 | 1.18M | { |
86 | 1.18M | FilmstripDemuxContext *film = s->priv_data; |
87 | 1.18M | AVStream *st = s->streams[0]; |
88 | | |
89 | 1.18M | if (avio_feof(s->pb)) |
90 | 1.38k | return AVERROR_EOF; |
91 | 1.18M | pkt->dts = avio_tell(s->pb) / (st->codecpar->width * (int64_t)(st->codecpar->height + film->leading) * 4); |
92 | 1.18M | pkt->size = av_get_packet(s->pb, pkt, st->codecpar->width * st->codecpar->height * 4); |
93 | 1.18M | avio_skip(s->pb, st->codecpar->width * (int64_t) film->leading * 4); |
94 | 1.18M | if (pkt->size < 0) |
95 | 439 | return pkt->size; |
96 | 1.18M | pkt->flags |= AV_PKT_FLAG_KEY; |
97 | 1.18M | return 0; |
98 | 1.18M | } |
99 | | |
100 | | static int read_seek(AVFormatContext *s, int stream_index, int64_t timestamp, int flags) |
101 | 0 | { |
102 | 0 | AVStream *st = s->streams[stream_index]; |
103 | 0 | if (avio_seek(s->pb, FFMAX(timestamp, 0) * st->codecpar->width * st->codecpar->height * 4, SEEK_SET) < 0) |
104 | 0 | return -1; |
105 | 0 | return 0; |
106 | 0 | } |
107 | | |
108 | | const FFInputFormat ff_filmstrip_demuxer = { |
109 | | .p.name = "filmstrip", |
110 | | .p.long_name = NULL_IF_CONFIG_SMALL("Adobe Filmstrip"), |
111 | | .p.extensions = "flm", |
112 | | .priv_data_size = sizeof(FilmstripDemuxContext), |
113 | | .read_header = read_header, |
114 | | .read_packet = read_packet, |
115 | | .read_seek = read_seek, |
116 | | }; |