]> git.sesse.net Git - ffmpeg/blob - libavformat/mvdec.c
mpegvideo_enc: export vbv_delay in side data
[ffmpeg] / libavformat / mvdec.c
1 /*
2  * Silicon Graphics Movie demuxer
3  * Copyright (c) 2012 Peter Ross
4  *
5  * This file is part of Libav.
6  *
7  * Libav 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  * Libav 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 Libav; 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  * Silicon Graphics Movie demuxer
25  */
26
27 #include "libavutil/channel_layout.h"
28 #include "libavutil/eval.h"
29 #include "libavutil/intreadwrite.h"
30 #include "libavutil/rational.h"
31
32 #include "avformat.h"
33 #include "internal.h"
34
35 typedef struct MvContext {
36     int nb_video_tracks;
37     int nb_audio_tracks;
38
39     int eof_count;        ///< number of streams that have finished
40     int stream_index;     ///< current stream index
41     int frame[2];         ///< frame nb for current stream
42
43     int acompression;     ///< compression level for audio stream
44     int aformat;          ///< audio format
45 } MvContext;
46
47 #define AUDIO_FORMAT_SIGNED 401
48
49 static int mv_probe(AVProbeData *p)
50 {
51     if (AV_RB32(p->buf) == MKBETAG('M', 'O', 'V', 'I') &&
52         AV_RB16(p->buf + 4) < 3)
53         return AVPROBE_SCORE_MAX;
54     return 0;
55 }
56
57 static char *var_read_string(AVIOContext *pb, int size)
58 {
59     int n;
60     char *str = av_malloc(size + 1);
61     if (!str)
62         return NULL;
63     n = avio_get_str(pb, size, str, size + 1);
64     if (n < size)
65         avio_skip(pb, size - n);
66     return str;
67 }
68
69 static int var_read_int(AVIOContext *pb, int size)
70 {
71     int v;
72     char *s = var_read_string(pb, size);
73     if (!s)
74         return 0;
75     v = strtol(s, NULL, 10);
76     av_free(s);
77     return v;
78 }
79
80 static AVRational var_read_float(AVIOContext *pb, int size)
81 {
82     AVRational v;
83     char *s = var_read_string(pb, size);
84     if (!s)
85         return (AVRational) { 0, 0 };
86     v = av_d2q(av_strtod(s, NULL), INT_MAX);
87     av_free(s);
88     return v;
89 }
90
91 static void var_read_metadata(AVFormatContext *avctx, const char *tag, int size)
92 {
93     char *value = var_read_string(avctx->pb, size);
94     if (value)
95         av_dict_set(&avctx->metadata, tag, value, AV_DICT_DONT_STRDUP_VAL);
96 }
97
98 static int set_channels(AVFormatContext *avctx, AVStream *st, int channels)
99 {
100     if (channels <= 0) {
101         av_log(avctx, AV_LOG_ERROR, "Channel count %d invalid.\n", channels);
102         return AVERROR_INVALIDDATA;
103     }
104     st->codec->channels       = channels;
105     st->codec->channel_layout = (st->codec->channels == 1) ? AV_CH_LAYOUT_MONO
106                                                            : AV_CH_LAYOUT_STEREO;
107     return 0;
108 }
109
110 /**
111  * Parse global variable
112  * @return < 0 if unknown
113  */
114 static int parse_global_var(AVFormatContext *avctx, AVStream *st,
115                             const char *name, int size)
116 {
117     MvContext *mv = avctx->priv_data;
118     AVIOContext *pb = avctx->pb;
119     if (!strcmp(name, "__NUM_I_TRACKS")) {
120         mv->nb_video_tracks = var_read_int(pb, size);
121     } else if (!strcmp(name, "__NUM_A_TRACKS")) {
122         mv->nb_audio_tracks = var_read_int(pb, size);
123     } else if (!strcmp(name, "COMMENT") || !strcmp(name, "TITLE")) {
124         var_read_metadata(avctx, name, size);
125     } else if (!strcmp(name, "LOOP_MODE") || !strcmp(name, "NUM_LOOPS") ||
126                !strcmp(name, "OPTIMIZED")) {
127         avio_skip(pb, size); // ignore
128     } else
129         return AVERROR_INVALIDDATA;
130
131     return 0;
132 }
133
134 /**
135  * Parse audio variable
136  * @return < 0 if unknown
137  */
138 static int parse_audio_var(AVFormatContext *avctx, AVStream *st,
139                            const char *name, int size)
140 {
141     MvContext *mv = avctx->priv_data;
142     AVIOContext *pb = avctx->pb;
143     if (!strcmp(name, "__DIR_COUNT")) {
144         st->nb_frames = var_read_int(pb, size);
145     } else if (!strcmp(name, "AUDIO_FORMAT")) {
146         mv->aformat = var_read_int(pb, size);
147     } else if (!strcmp(name, "COMPRESSION")) {
148         mv->acompression = var_read_int(pb, size);
149     } else if (!strcmp(name, "DEFAULT_VOL")) {
150         var_read_metadata(avctx, name, size);
151     } else if (!strcmp(name, "NUM_CHANNELS")) {
152         return set_channels(avctx, st, var_read_int(pb, size));
153     } else if (!strcmp(name, "SAMPLE_RATE")) {
154         st->codec->sample_rate = var_read_int(pb, size);
155         avpriv_set_pts_info(st, 33, 1, st->codec->sample_rate);
156     } else if (!strcmp(name, "SAMPLE_WIDTH")) {
157         st->codec->bits_per_coded_sample = var_read_int(pb, size) * 8;
158     } else
159         return AVERROR_INVALIDDATA;
160
161     return 0;
162 }
163
164 /**
165  * Parse video variable
166  * @return < 0 if unknown
167  */
168 static int parse_video_var(AVFormatContext *avctx, AVStream *st,
169                            const char *name, int size)
170 {
171     AVIOContext *pb = avctx->pb;
172     if (!strcmp(name, "__DIR_COUNT")) {
173         st->nb_frames = st->duration = var_read_int(pb, size);
174     } else if (!strcmp(name, "COMPRESSION")) {
175         char *str = var_read_string(pb, size);
176         if (!str)
177             return AVERROR_INVALIDDATA;
178         if (!strcmp(str, "1")) {
179             st->codec->codec_id = AV_CODEC_ID_MVC1;
180         } else if (!strcmp(str, "2")) {
181             st->codec->pix_fmt  = AV_PIX_FMT_ABGR;
182             st->codec->codec_id = AV_CODEC_ID_RAWVIDEO;
183         } else if (!strcmp(str, "3")) {
184             st->codec->codec_id = AV_CODEC_ID_SGIRLE;
185         } else if (!strcmp(str, "10")) {
186             st->codec->codec_id = AV_CODEC_ID_MJPEG;
187         } else if (!strcmp(str, "MVC2")) {
188             st->codec->codec_id = AV_CODEC_ID_MVC2;
189         } else {
190             avpriv_request_sample(avctx, "Video compression %s", str);
191         }
192         av_free(str);
193     } else if (!strcmp(name, "FPS")) {
194         AVRational fps = var_read_float(pb, size);
195         avpriv_set_pts_info(st, 64, fps.den, fps.num);
196         st->avg_frame_rate = fps;
197     } else if (!strcmp(name, "HEIGHT")) {
198         st->codec->height = var_read_int(pb, size);
199     } else if (!strcmp(name, "PIXEL_ASPECT")) {
200         st->sample_aspect_ratio = var_read_float(pb, size);
201         av_reduce(&st->sample_aspect_ratio.num, &st->sample_aspect_ratio.den,
202                   st->sample_aspect_ratio.num, st->sample_aspect_ratio.den,
203                   INT_MAX);
204     } else if (!strcmp(name, "WIDTH")) {
205         st->codec->width = var_read_int(pb, size);
206     } else if (!strcmp(name, "ORIENTATION")) {
207         if (var_read_int(pb, size) == 1101) {
208             st->codec->extradata      = av_strdup("BottomUp");
209             st->codec->extradata_size = 9;
210         }
211     } else if (!strcmp(name, "Q_SPATIAL") || !strcmp(name, "Q_TEMPORAL")) {
212         var_read_metadata(avctx, name, size);
213     } else if (!strcmp(name, "INTERLACING") || !strcmp(name, "PACKING")) {
214         avio_skip(pb, size); // ignore
215     } else
216         return AVERROR_INVALIDDATA;
217
218     return 0;
219 }
220
221 static void read_table(AVFormatContext *avctx, AVStream *st,
222                        int (*parse)(AVFormatContext *avctx, AVStream *st,
223                                     const char *name, int size))
224 {
225     int count, i;
226     AVIOContext *pb = avctx->pb;
227     avio_skip(pb, 4);
228     count = avio_rb32(pb);
229     avio_skip(pb, 4);
230     for (i = 0; i < count; i++) {
231         char name[17];
232         int size;
233         avio_read(pb, name, 16);
234         name[sizeof(name) - 1] = 0;
235         size = avio_rb32(pb);
236         if (parse(avctx, st, name, size) < 0) {
237             avpriv_request_sample(avctx, "Variable %s", name);
238             avio_skip(pb, size);
239         }
240     }
241 }
242
243 static void read_index(AVIOContext *pb, AVStream *st)
244 {
245     uint64_t timestamp = 0;
246     int i;
247     for (i = 0; i < st->nb_frames; i++) {
248         uint32_t pos  = avio_rb32(pb);
249         uint32_t size = avio_rb32(pb);
250         avio_skip(pb, 8);
251         av_add_index_entry(st, pos, timestamp, size, 0, AVINDEX_KEYFRAME);
252         if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
253             timestamp += size / (st->codec->channels * 2);
254         } else {
255             timestamp++;
256         }
257     }
258 }
259
260 static int mv_read_header(AVFormatContext *avctx)
261 {
262     MvContext *mv = avctx->priv_data;
263     AVIOContext *pb = avctx->pb;
264     AVStream *ast = NULL, *vst = NULL;
265     int version, i;
266
267     avio_skip(pb, 4);
268
269     version = avio_rb16(pb);
270     if (version == 2) {
271         uint64_t timestamp;
272         int v;
273         avio_skip(pb, 22);
274
275         /* allocate audio track first to prevent unnecessary seeking
276          * (audio packet always precede video packet for a given frame) */
277         ast = avformat_new_stream(avctx, NULL);
278         if (!ast)
279             return AVERROR(ENOMEM);
280
281         vst = avformat_new_stream(avctx, NULL);
282         if (!vst)
283             return AVERROR(ENOMEM);
284         avpriv_set_pts_info(vst, 64, 1, 15);
285         vst->codec->codec_type = AVMEDIA_TYPE_VIDEO;
286         vst->avg_frame_rate    = av_inv_q(vst->time_base);
287         vst->nb_frames         = avio_rb32(pb);
288         v = avio_rb32(pb);
289         switch (v) {
290         case 1:
291             vst->codec->codec_id = AV_CODEC_ID_MVC1;
292             break;
293         case 2:
294             vst->codec->pix_fmt  = AV_PIX_FMT_ARGB;
295             vst->codec->codec_id = AV_CODEC_ID_RAWVIDEO;
296             break;
297         default:
298             avpriv_request_sample(avctx, "Video compression %i", v);
299             break;
300         }
301         vst->codec->codec_tag = 0;
302         vst->codec->width     = avio_rb32(pb);
303         vst->codec->height    = avio_rb32(pb);
304         avio_skip(pb, 12);
305
306         ast->codec->codec_type  = AVMEDIA_TYPE_AUDIO;
307         ast->nb_frames          = vst->nb_frames;
308         ast->codec->sample_rate = avio_rb32(pb);
309         avpriv_set_pts_info(ast, 33, 1, ast->codec->sample_rate);
310         if (set_channels(avctx, ast, avio_rb32(pb)) < 0)
311             return AVERROR_INVALIDDATA;
312
313         v = avio_rb32(pb);
314         if (v == AUDIO_FORMAT_SIGNED) {
315             ast->codec->codec_id = AV_CODEC_ID_PCM_S16BE;
316         } else {
317             avpriv_request_sample(avctx, "Audio compression (format %i)", v);
318         }
319
320         avio_skip(pb, 12);
321         var_read_metadata(avctx, "title", 0x80);
322         var_read_metadata(avctx, "comment", 0x100);
323         avio_skip(pb, 0x80);
324
325         timestamp = 0;
326         for (i = 0; i < vst->nb_frames; i++) {
327             uint32_t pos   = avio_rb32(pb);
328             uint32_t asize = avio_rb32(pb);
329             uint32_t vsize = avio_rb32(pb);
330             avio_skip(pb, 8);
331             av_add_index_entry(ast, pos, timestamp, asize, 0, AVINDEX_KEYFRAME);
332             av_add_index_entry(vst, pos + asize, i, vsize, 0, AVINDEX_KEYFRAME);
333             timestamp += asize / (ast->codec->channels * 2);
334         }
335     } else if (!version && avio_rb16(pb) == 3) {
336         avio_skip(pb, 4);
337
338         read_table(avctx, NULL, parse_global_var);
339
340         if (mv->nb_audio_tracks > 1) {
341             avpriv_request_sample(avctx, "Multiple audio streams support");
342             return AVERROR_PATCHWELCOME;
343         } else if (mv->nb_audio_tracks) {
344             ast = avformat_new_stream(avctx, NULL);
345             if (!ast)
346                 return AVERROR(ENOMEM);
347             ast->codec->codec_type = AVMEDIA_TYPE_AUDIO;
348             read_table(avctx, ast, parse_audio_var);
349             if (mv->acompression == 100 &&
350                 mv->aformat == AUDIO_FORMAT_SIGNED &&
351                 ast->codec->bits_per_coded_sample == 16) {
352                 ast->codec->codec_id = AV_CODEC_ID_PCM_S16BE;
353             } else {
354                 avpriv_request_sample(avctx,
355                                       "Audio compression %i (format %i, sr %i)",
356                                       mv->acompression, mv->aformat,
357                                       ast->codec->bits_per_coded_sample);
358                 ast->codec->codec_id = AV_CODEC_ID_NONE;
359             }
360             if (ast->codec->channels <= 0) {
361                 av_log(avctx, AV_LOG_ERROR, "No valid channel count found.\n");
362                 return AVERROR_INVALIDDATA;
363             }
364         }
365
366         if (mv->nb_video_tracks > 1) {
367             avpriv_request_sample(avctx, "Multiple video streams support");
368             return AVERROR_PATCHWELCOME;
369         } else if (mv->nb_video_tracks) {
370             vst = avformat_new_stream(avctx, NULL);
371             if (!vst)
372                 return AVERROR(ENOMEM);
373             vst->codec->codec_type = AVMEDIA_TYPE_VIDEO;
374             read_table(avctx, vst, parse_video_var);
375         }
376
377         if (mv->nb_audio_tracks)
378             read_index(pb, ast);
379
380         if (mv->nb_video_tracks)
381             read_index(pb, vst);
382     } else {
383         avpriv_request_sample(avctx, "Version %i", version);
384         return AVERROR_PATCHWELCOME;
385     }
386
387     return 0;
388 }
389
390 static int mv_read_packet(AVFormatContext *avctx, AVPacket *pkt)
391 {
392     MvContext *mv = avctx->priv_data;
393     AVIOContext *pb = avctx->pb;
394     AVStream *st = avctx->streams[mv->stream_index];
395     const AVIndexEntry *index;
396     int frame = mv->frame[mv->stream_index];
397     int ret;
398     uint64_t pos;
399
400     if (frame < st->nb_index_entries) {
401         index = &st->index_entries[frame];
402         pos   = avio_tell(pb);
403         if (index->pos > pos)
404             avio_skip(pb, index->pos - pos);
405         else if (index->pos < pos) {
406             if (!pb->seekable)
407                 return AVERROR(EIO);
408             ret = avio_seek(pb, index->pos, SEEK_SET);
409             if (ret < 0)
410                 return ret;
411         }
412         ret = av_get_packet(pb, pkt, index->size);
413         if (ret < 0)
414             return ret;
415
416         pkt->stream_index = mv->stream_index;
417         pkt->pts          = index->timestamp;
418         pkt->flags       |= AV_PKT_FLAG_KEY;
419
420         mv->frame[mv->stream_index]++;
421         mv->eof_count = 0;
422     } else {
423         mv->eof_count++;
424         if (mv->eof_count >= avctx->nb_streams)
425             return AVERROR_EOF;
426
427         // avoid returning 0 without a packet
428         return AVERROR(EAGAIN);
429     }
430
431     mv->stream_index++;
432     if (mv->stream_index >= avctx->nb_streams)
433         mv->stream_index = 0;
434
435     return 0;
436 }
437
438 static int mv_read_seek(AVFormatContext *avctx, int stream_index,
439                         int64_t timestamp, int flags)
440 {
441     MvContext *mv = avctx->priv_data;
442     AVStream *st = avctx->streams[stream_index];
443     int frame, i;
444
445     if ((flags & AVSEEK_FLAG_FRAME) || (flags & AVSEEK_FLAG_BYTE))
446         return AVERROR(ENOSYS);
447
448     if (!avctx->pb->seekable)
449         return AVERROR(EIO);
450
451     frame = av_index_search_timestamp(st, timestamp, flags);
452     if (frame < 0)
453         return AVERROR_INVALIDDATA;
454
455     for (i = 0; i < avctx->nb_streams; i++)
456         mv->frame[i] = frame;
457     return 0;
458 }
459
460 AVInputFormat ff_mv_demuxer = {
461     .name           = "mv",
462     .long_name      = NULL_IF_CONFIG_SMALL("Silicon Graphics Movie"),
463     .priv_data_size = sizeof(MvContext),
464     .read_probe     = mv_probe,
465     .read_header    = mv_read_header,
466     .read_packet    = mv_read_packet,
467     .read_seek      = mv_read_seek,
468 };