3 * Copyright (c) 2006 Reimar Doeffinger.
5 * This file is part of FFmpeg.
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.
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.
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
37 static int nuv_probe(AVProbeData
*p
) {
40 if (!memcmp(p
->buf
, "NuppelVideo", 12))
41 return AVPROBE_SCORE_MAX
;
42 if (!memcmp(p
->buf
, "MythTVVideo", 12))
43 return AVPROBE_SCORE_MAX
;
47 //! little macro to sanitize packet size
48 #define PKTSIZE(s) (s & 0xffffff)
51 * \brief read until we found all data needed for decoding
52 * \param vst video stream of which to change parameters
53 * \param ast video stream of which to change parameters
54 * \param myth set if this is a MythTVVideo format file
55 * \return 1 if all required codec data was found
57 static int get_codec_data(ByteIOContext
*pb
, AVStream
*vst
,
58 AVStream
*ast
, int myth
) {
59 frametype_t frametype
;
61 return 1; // no codec data needed
62 while (!url_feof(pb
)) {
64 frametype
= get_byte(pb
);
67 subtype
= get_byte(pb
);
69 size
= PKTSIZE(get_le32(pb
));
70 if (vst
&& subtype
== 'R') {
71 vst
->codec
->extradata_size
= size
;
72 vst
->codec
->extradata
= av_malloc(size
);
73 get_buffer(pb
, vst
->codec
->extradata
, size
);
81 size
= PKTSIZE(get_le32(pb
));
84 get_le32(pb
); // version
86 vst
->codec
->codec_tag
= get_le32(pb
);
87 vst
->codec
->codec_id
=
88 codec_get_id(codec_bmp_tags
, vst
->codec
->codec_tag
);
93 ast
->codec
->codec_tag
= get_le32(pb
);
94 ast
->codec
->sample_rate
= get_le32(pb
);
95 ast
->codec
->bits_per_sample
= get_le32(pb
);
96 ast
->codec
->channels
= get_le32(pb
);
97 ast
->codec
->codec_id
=
98 wav_codec_get_id(ast
->codec
->codec_tag
,
99 ast
->codec
->bits_per_sample
);
101 url_fskip(pb
, 4 * 4);
111 size
= PKTSIZE(get_le32(pb
));
119 static int nuv_header(AVFormatContext
*s
, AVFormatParameters
*ap
) {
120 NUVContext
*ctx
= (NUVContext
*)s
->priv_data
;
121 ByteIOContext
*pb
= &s
->pb
;
122 char id_string
[12], version_string
[5];
124 int is_mythtv
, width
, height
, v_packs
, a_packs
;
126 AVStream
*vst
= NULL
, *ast
= NULL
;
127 get_buffer(pb
, id_string
, 12);
128 is_mythtv
= !memcmp(id_string
, "MythTVVideo", 12);
129 get_buffer(pb
, version_string
, 5);
130 url_fskip(pb
, 3); // padding
131 width
= get_le32(pb
);
132 height
= get_le32(pb
);
133 get_le32(pb
); // unused, "desiredwidth"
134 get_le32(pb
); // unused, "desiredheight"
135 get_byte(pb
); // 'P' == progressive, 'I' == interlaced
136 url_fskip(pb
, 3); // padding
137 aspect
= av_int2dbl(get_le64(pb
));
138 fps
= av_int2dbl(get_le64(pb
));
140 // number of packets per stream type, -1 means unknown, e.g. streaming
141 v_packs
= get_le32(pb
);
142 a_packs
= get_le32(pb
);
143 get_le32(pb
); // text
145 get_le32(pb
); // keyframe distance (?)
148 ctx
->v_id
= stream_nr
++;
149 vst
= av_new_stream(s
, ctx
->v_id
);
150 vst
->codec
->codec_type
= CODEC_TYPE_VIDEO
;
151 vst
->codec
->codec_id
= CODEC_ID_NUV
;
152 vst
->codec
->codec_tag
= MKTAG('R', 'J', 'P', 'G');
153 vst
->codec
->width
= width
;
154 vst
->codec
->height
= height
;
155 vst
->codec
->bits_per_sample
= 10;
156 vst
->codec
->sample_aspect_ratio
= av_d2q(aspect
, 10000);
157 vst
->r_frame_rate
= av_d2q(1.0 / fps
, 10000);
158 av_set_pts_info(vst
, 32, 1, 1000);
163 ctx
->a_id
= stream_nr
++;
164 ast
= av_new_stream(s
, ctx
->a_id
);
165 ast
->codec
->codec_type
= CODEC_TYPE_AUDIO
;
166 ast
->codec
->codec_id
= CODEC_ID_PCM_S16LE
;
167 ast
->codec
->channels
= 2;
168 ast
->codec
->sample_rate
= 44100;
169 ast
->codec
->bit_rate
= 2 * 2 * 44100 * 8;
170 ast
->codec
->block_align
= 2 * 2;
171 ast
->codec
->bits_per_sample
= 16;
172 av_set_pts_info(ast
, 32, 1, 1000);
176 get_codec_data(pb
, vst
, ast
, is_mythtv
);
182 static int nuv_packet(AVFormatContext
*s
, AVPacket
*pkt
) {
183 NUVContext
*ctx
= (NUVContext
*)s
->priv_data
;
184 ByteIOContext
*pb
= &s
->pb
;
185 uint8_t hdr
[HDRSIZE
];
186 frametype_t frametype
;
188 while (!url_feof(pb
)) {
189 ret
= get_buffer(pb
, hdr
, HDRSIZE
);
191 return ret
? ret
: -1;
193 size
= PKTSIZE(AV_RL32(&hdr
[8]));
198 av_log(s
, AV_LOG_ERROR
, "Video packet in file without video stream!\n");
202 ret
= av_new_packet(pkt
, HDRSIZE
+ size
);
205 pkt
->pos
= url_ftell(pb
);
206 pkt
->pts
= AV_RL32(&hdr
[4]);
207 pkt
->stream_index
= ctx
->v_id
;
208 memcpy(pkt
->data
, hdr
, HDRSIZE
);
209 ret
= get_buffer(pb
, pkt
->data
+ HDRSIZE
, size
);
213 av_log(s
, AV_LOG_ERROR
, "Audio packet in file without audio stream!\n");
217 ret
= av_get_packet(pb
, pkt
, size
);
218 pkt
->pts
= AV_RL32(&hdr
[4]);
219 pkt
->stream_index
= ctx
->a_id
;
222 // contains no data, size value is invalid
232 AVInputFormat nuv_demuxer
= {
234 "NuppelVideo format",