FFmpeg
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
gdv.c
Go to the documentation of this file.
1 /*
2  * Gremlin Digital Video demuxer
3  * Copyright (c) 2017 Paul B Mahol
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 #include "libavutil/intreadwrite.h"
23 
24 #include "avformat.h"
25 #include "avio.h"
26 #include "internal.h"
27 
28 typedef struct GDVContext {
30  int is_audio;
34  unsigned pal[256];
35 } GDVContext;
36 
38 {
39  if (AV_RL32(p->buf) == 0x29111994)
40  return AVPROBE_SCORE_MAX;
41 
42  return 0;
43 }
44 
45 static struct {
46  uint16_t id;
47  uint16_t width;
48  uint16_t height;
49 } FixedSize[] = {
50  { 0, 320, 200},
51  { 1, 640, 200},
52  { 2, 320, 167},
53  { 3, 320, 180},
54  { 4, 320, 400},
55  { 5, 320, 170},
56  { 6, 160, 85},
57  { 7, 160, 83},
58  { 8, 160, 90},
59  { 9, 280, 128},
60  {10, 320, 240},
61  {11, 320, 201},
62  {16, 640, 400},
63  {17, 640, 200},
64  {18, 640, 180},
65  {19, 640, 167},
66  {20, 640, 170},
67  {21, 320, 240}
68 };
69 
71 {
72  GDVContext *gdv = ctx->priv_data;
73  AVIOContext *pb = ctx->pb;
74  AVStream *vst, *ast;
75  unsigned fps, snd_flags, vid_depth, size_id;
76 
77  avio_skip(pb, 4);
78  size_id = avio_rl16(pb);
79 
80  vst = avformat_new_stream(ctx, 0);
81  if (!vst)
82  return AVERROR(ENOMEM);
83 
84  vst->start_time = 0;
85  vst->duration =
86  vst->nb_frames = avio_rl16(pb);
87 
88  fps = avio_rl16(pb);
89  snd_flags = avio_rl16(pb);
90  if (snd_flags & 1) {
91  ast = avformat_new_stream(ctx, 0);
92  if (!ast)
93  return AVERROR(ENOMEM);
94 
95  ast->start_time = 0;
97  ast->codecpar->codec_tag = 0;
98  ast->codecpar->sample_rate = avio_rl16(pb);
99  ast->codecpar->channels = 1 + !!(snd_flags & 2);
100  if (snd_flags & 8) {
102  } else {
103  ast->codecpar->codec_id = (snd_flags & 4) ? AV_CODEC_ID_PCM_S16LE : AV_CODEC_ID_PCM_U8;
104  }
105 
106  avpriv_set_pts_info(ast, 64, 1, ast->codecpar->sample_rate);
107  gdv->audio_size = (ast->codecpar->sample_rate / fps) *
108  ast->codecpar->channels * (1 + !!(snd_flags & 4)) / (1 + !!(snd_flags & 8));
109  gdv->is_audio = 1;
110  } else {
111  avio_skip(pb, 2);
112  }
113  vid_depth = avio_rl16(pb);
114  avio_skip(pb, 4);
115 
118  vst->codecpar->codec_tag = 0;
119  vst->codecpar->width = avio_rl16(pb);
120  vst->codecpar->height = avio_rl16(pb);
121 
122  if (vst->codecpar->width == 0 || vst->codecpar->height == 0) {
123  int i;
124 
125  for (i = 0; i < FF_ARRAY_ELEMS(FixedSize) - 1; i++) {
126  if (FixedSize[i].id == size_id)
127  break;
128  }
129 
130  vst->codecpar->width = FixedSize[i].width;
131  vst->codecpar->height = FixedSize[i].height;
132  }
133 
134  avpriv_set_pts_info(vst, 64, 1, fps);
135 
136  if (vid_depth & 1) {
137  int i;
138 
139  for (i = 0; i < 256; i++) {
140  unsigned r = avio_r8(pb);
141  unsigned g = avio_r8(pb);
142  unsigned b = avio_r8(pb);
143  gdv->pal[i] = 0xFFU << 24 | r << 18 | g << 10 | b << 2;
144  }
145  }
146 
147  gdv->is_first_video = 1;
148 
149  return 0;
150 }
151 
153 {
154  GDVContext *gdv = ctx->priv_data;
155  AVIOContext *pb = ctx->pb;
156  int ret;
157 
158  if (avio_feof(pb))
159  return pb->error ? pb->error : AVERROR_EOF;
160 
161  if (gdv->audio_size && gdv->is_audio) {
162  ret = av_get_packet(pb, pkt, gdv->audio_size);
163  if (ret < 0)
164  return ret;
165  pkt->stream_index = 1;
166  gdv->is_audio = 0;
167  } else {
168  uint8_t *pal;
169 
170  if (avio_rl16(pb) != 0x1305)
171  return AVERROR_INVALIDDATA;
172  ret = av_get_packet(pb, pkt, 4 + avio_rl16(pb));
173  if (ret < 0)
174  return ret;
175  pkt->stream_index = 0;
176  gdv->is_audio = 1;
177 
178  if (gdv->is_first_video) {
181  if (!pal) {
182  av_packet_unref(pkt);
183  return AVERROR(ENOMEM);
184  }
185  memcpy(pal, gdv->pal, AVPALETTE_SIZE);
186  pkt->flags |= AV_PKT_FLAG_KEY;
187  gdv->is_first_video = 0;
188  }
189  }
190 
191  return 0;
192 }
193 
195  .name = "gdv",
196  .long_name = NULL_IF_CONFIG_SMALL("Gremlin Digital Video"),
197  .priv_data_size = sizeof(GDVContext),
201 };
Bytestream IO Context.
Definition: avio.h:161
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:59
Buffered I/O operations.
void avpriv_set_pts_info(AVStream *s, int pts_wrap_bits, unsigned int pts_num, unsigned int pts_den)
Set the time base and wrapping info for a given stream.
Definition: utils.c:4882
const char * g
Definition: vf_curves.c:115
static int gdv_read_packet(AVFormatContext *ctx, AVPacket *pkt)
Definition: gdv.c:152
AVInputFormat ff_gdv_demuxer
Definition: gdv.c:194
enum AVCodecID codec_id
Specific type of the encoded data (the codec used).
Definition: avcodec.h:3900
const char * b
Definition: vf_curves.c:116
int64_t avio_skip(AVIOContext *s, int64_t offset)
Skip given number of bytes forward.
Definition: aviobuf.c:331
static AVPacket pkt
Format I/O context.
Definition: avformat.h:1351
int is_audio
Definition: gdv.c:30
uint8_t
int width
Video only.
Definition: avcodec.h:3966
#define AVPALETTE_SIZE
Definition: pixfmt.h:32
AVStream * avformat_new_stream(AVFormatContext *s, const AVCodec *c)
Add a new stream to a media file.
Definition: utils.c:4455
#define AVERROR_EOF
End of file.
Definition: error.h:55
int av_get_packet(AVIOContext *s, AVPacket *pkt, int size)
Allocate and read the payload of a packet and initialize its fields with default values.
Definition: utils.c:310
#define AV_PKT_FLAG_KEY
The packet contains a keyframe.
Definition: avcodec.h:1477
uint32_t pal[256]
Definition: gdv.c:35
#define U(x)
Definition: vp56_arith.h:37
An AV_PKT_DATA_PALETTE side data packet contains exactly AVPALETTE_SIZE bytes worth of palette...
Definition: avcodec.h:1158
#define AVERROR(e)
Definition: error.h:43
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
Definition: internal.h:186
const char * r
Definition: vf_curves.c:114
enum AVMediaType codec_type
General type of the encoded data.
Definition: avcodec.h:3896
Definition: gdv.c:28
uint16_t width
Definition: gdv.c:47
int flags
A combination of AV_PKT_FLAG values.
Definition: avcodec.h:1451
int avio_r8(AVIOContext *s)
Definition: aviobuf.c:639
unsigned char * buf
Buffer must have AVPROBE_PADDING_SIZE of extra allocated bytes filled with zero.
Definition: avformat.h:450
static int read_probe(AVProbeData *pd)
Definition: jvdec.c:55
AVFormatContext * ctx
Definition: movenc.c:48
int audio_stream_index
Definition: gdv.c:32
#define FF_ARRAY_ELEMS(a)
static int read_header(FFV1Context *f)
Definition: ffv1dec.c:530
Stream structure.
Definition: avformat.h:874
static int read_packet(void *opaque, uint8_t *buf, int buf_size)
Definition: avio_reading.c:42
AVIOContext * pb
I/O context.
Definition: avformat.h:1393
uint16_t height
Definition: gdv.c:48
void av_packet_unref(AVPacket *pkt)
Wipe the packet.
Definition: avpacket.c:598
uint16_t id
Definition: gdv.c:46
int is_first_video
Definition: gdv.c:29
int video_stream_index
Definition: gdv.c:33
int error
contains the error code or 0 if no error happened
Definition: avio.h:245
This structure contains the data a format has to probe a file.
Definition: avformat.h:448
static struct @250 FixedSize[]
int64_t duration
Decoding: duration of the stream, in stream time base.
Definition: avformat.h:923
int sample_rate
Audio only.
Definition: avcodec.h:4010
#define AVPROBE_SCORE_MAX
maximum score
Definition: avformat.h:460
unsigned int avio_rl16(AVIOContext *s)
Definition: aviobuf.c:754
Main libavformat public API header.
static int gdv_read_header(AVFormatContext *ctx)
Definition: gdv.c:70
int64_t start_time
Decoding: pts of the first frame of the stream in presentation order, in stream time base...
Definition: avformat.h:913
int64_t nb_frames
number of frames in this stream if known or 0
Definition: avformat.h:925
static int gdv_read_probe(AVProbeData *p)
Definition: gdv.c:37
int audio_size
Definition: gdv.c:31
void * priv_data
Format private data.
Definition: avformat.h:1379
int channels
Audio only.
Definition: avcodec.h:4006
const char * name
A comma separated list of short names for the format.
Definition: avformat.h:647
AVCodecParameters * codecpar
Codec parameters associated with this stream.
Definition: avformat.h:1021
int avio_feof(AVIOContext *s)
feof() equivalent for AVIOContext.
Definition: aviobuf.c:358
uint32_t codec_tag
Additional information about the codec (corresponds to the AVI FOURCC).
Definition: avcodec.h:3904
uint8_t * av_packet_new_side_data(AVPacket *pkt, enum AVPacketSideDataType type, int size)
Allocate new information of a packet.
Definition: avpacket.c:329
int stream_index
Definition: avcodec.h:1447
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_RL32
Definition: bytestream.h:87
This structure stores compressed data.
Definition: avcodec.h:1422