FFmpeg  4.3.7
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 
37 static int gdv_read_probe(const AVProbeData *p)
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  if (!fps)
90  return AVERROR_INVALIDDATA;
91 
92  snd_flags = avio_rl16(pb);
93  if (snd_flags & 1) {
94  ast = avformat_new_stream(ctx, 0);
95  if (!ast)
96  return AVERROR(ENOMEM);
97 
98  ast->start_time = 0;
100  ast->codecpar->codec_tag = 0;
101  ast->codecpar->sample_rate = avio_rl16(pb);
102  ast->codecpar->channels = 1 + !!(snd_flags & 2);
103  if (snd_flags & 8) {
105  } else {
106  ast->codecpar->codec_id = (snd_flags & 4) ? AV_CODEC_ID_PCM_S16LE : AV_CODEC_ID_PCM_U8;
107  }
108 
109  avpriv_set_pts_info(ast, 64, 1, ast->codecpar->sample_rate);
110  gdv->audio_size = (ast->codecpar->sample_rate / fps) *
111  ast->codecpar->channels * (1 + !!(snd_flags & 4)) / (1 + !!(snd_flags & 8));
112  gdv->is_audio = 1;
113  } else {
114  avio_skip(pb, 2);
115  }
116  vid_depth = avio_rl16(pb);
117  avio_skip(pb, 4);
118 
121  vst->codecpar->codec_tag = 0;
122  vst->codecpar->width = avio_rl16(pb);
123  vst->codecpar->height = avio_rl16(pb);
124 
125  if (vst->codecpar->width == 0 || vst->codecpar->height == 0) {
126  int i;
127 
128  for (i = 0; i < FF_ARRAY_ELEMS(FixedSize) - 1; i++) {
129  if (FixedSize[i].id == size_id)
130  break;
131  }
132 
133  vst->codecpar->width = FixedSize[i].width;
134  vst->codecpar->height = FixedSize[i].height;
135  }
136 
137  avpriv_set_pts_info(vst, 64, 1, fps);
138 
139  if (vid_depth & 1) {
140  int i;
141 
142  for (i = 0; i < 256; i++) {
143  unsigned r = avio_r8(pb);
144  unsigned g = avio_r8(pb);
145  unsigned b = avio_r8(pb);
146  gdv->pal[i] = 0xFFU << 24 | r << 18 | g << 10 | b << 2;
147  }
148  }
149 
150  gdv->is_first_video = 1;
151 
152  return 0;
153 }
154 
156 {
157  GDVContext *gdv = ctx->priv_data;
158  AVIOContext *pb = ctx->pb;
159  int ret;
160 
161  if (avio_feof(pb))
162  return pb->error ? pb->error : AVERROR_EOF;
163 
164  if (gdv->audio_size && gdv->is_audio) {
165  ret = av_get_packet(pb, pkt, gdv->audio_size);
166  if (ret < 0)
167  return ret;
168  pkt->stream_index = 1;
169  gdv->is_audio = 0;
170  } else {
171  uint8_t *pal;
172 
173  if (avio_rl16(pb) != 0x1305)
174  return AVERROR_INVALIDDATA;
175  ret = av_get_packet(pb, pkt, 4 + avio_rl16(pb));
176  if (ret < 0)
177  return ret;
178  pkt->stream_index = 0;
179  gdv->is_audio = 1;
180 
181  if (gdv->is_first_video) {
184  if (!pal) {
185  return AVERROR(ENOMEM);
186  }
187  memcpy(pal, gdv->pal, AVPALETTE_SIZE);
188  pkt->flags |= AV_PKT_FLAG_KEY;
189  gdv->is_first_video = 0;
190  }
191  }
192 
193  return 0;
194 }
195 
197  .name = "gdv",
198  .long_name = NULL_IF_CONFIG_SMALL("Gremlin Digital Video"),
199  .priv_data_size = sizeof(GDVContext),
203 };
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:4948
const char * g
Definition: vf_curves.c:115
static int gdv_read_packet(AVFormatContext *ctx, AVPacket *pkt)
Definition: gdv.c:155
AVInputFormat ff_gdv_demuxer
Definition: gdv.c:196
enum AVCodecID codec_id
Specific type of the encoded data (the codec used).
Definition: codec_par.h:60
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:329
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: codec_par.h:126
#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:4526
#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:307
static struct @253 FixedSize[]
#define AV_PKT_FLAG_KEY
The packet contains a keyframe.
Definition: packet.h:388
uint32_t pal[256]
Definition: gdv.c:35
#define U(x)
Definition: vp56_arith.h:37
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:269
An AV_PKT_DATA_PALETTE side data packet contains exactly AVPALETTE_SIZE bytes worth of palette...
Definition: packet.h:46
#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:188
const char * r
Definition: vf_curves.c:114
enum AVMediaType codec_type
General type of the encoded data.
Definition: codec_par.h:56
Definition: gdv.c:28
uint16_t width
Definition: gdv.c:47
int flags
A combination of AV_PKT_FLAG values.
Definition: packet.h:361
int avio_r8(AVIOContext *s)
Definition: aviobuf.c:616
unsigned char * buf
Buffer must have AVPROBE_PADDING_SIZE of extra allocated bytes filled with zero.
Definition: avformat.h:443
AVFormatContext * ctx
Definition: movenc.c:48
#define AV_RL32
Definition: intreadwrite.h:146
int audio_stream_index
Definition: gdv.c:32
#define FF_ARRAY_ELEMS(a)
static int read_header(FFV1Context *f)
Definition: ffv1dec.c:545
Stream structure.
Definition: avformat.h:876
static int read_packet(void *opaque, uint8_t *buf, int buf_size)
Definition: avio_reading.c:42
static int gdv_read_probe(const AVProbeData *p)
Definition: gdv.c:37
AVIOContext * pb
I/O context.
Definition: avformat.h:1393
uint16_t height
Definition: gdv.c:48
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:441
static int read_probe(const AVProbeData *pd)
Definition: jvdec.c:55
int64_t duration
Decoding: duration of the stream, in stream time base.
Definition: avformat.h:925
int sample_rate
Audio only.
Definition: codec_par.h:170
#define AVPROBE_SCORE_MAX
maximum score
Definition: avformat.h:453
unsigned int avio_rl16(AVIOContext *s)
Definition: aviobuf.c:731
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:915
int64_t nb_frames
number of frames in this stream if known or 0
Definition: avformat.h:927
int audio_size
Definition: gdv.c:31
void * priv_data
Format private data.
Definition: avformat.h:1379
int channels
Audio only.
Definition: codec_par.h:166
const char * name
A comma separated list of short names for the format.
Definition: avformat.h:650
AVCodecParameters * codecpar
Codec parameters associated with this stream.
Definition: avformat.h:1023
int avio_feof(AVIOContext *s)
Similar to feof() but also returns nonzero on read errors.
Definition: aviobuf.c:356
uint32_t codec_tag
Additional information about the codec (corresponds to the AVI FOURCC).
Definition: codec_par.h:64
uint8_t * av_packet_new_side_data(AVPacket *pkt, enum AVPacketSideDataType type, int size)
Allocate new information of a packet.
Definition: avpacket.c:332
int stream_index
Definition: packet.h:357
This structure stores compressed data.
Definition: packet.h:332
PutByteContext pb
Definition: gdv.c:33