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
38 static int nuv_probe(AVProbeData
*p
) {
39 if (!memcmp(p
->buf
, "NuppelVideo", 12))
40 return AVPROBE_SCORE_MAX
;
41 if (!memcmp(p
->buf
, "MythTVVideo", 12))
42 return AVPROBE_SCORE_MAX
;
46 //! little macro to sanitize packet size
47 #define PKTSIZE(s) (s & 0xffffff)
50 * \brief read until we found all data needed for decoding
51 * \param vst video stream of which to change parameters
52 * \param ast video stream of which to change parameters
53 * \param myth set if this is a MythTVVideo format file
54 * \return 1 if all required codec data was found
56 static int get_codec_data(ByteIOContext
*pb
, AVStream
*vst
,
57 AVStream
*ast
, int myth
) {
58 frametype_t frametype
;
60 return 1; // no codec data needed
61 while (!url_feof(pb
)) {
63 frametype
= get_byte(pb
);
66 subtype
= get_byte(pb
);
68 size
= PKTSIZE(get_le32(pb
));
69 if (vst
&& subtype
== 'R') {
70 vst
->codec
->extradata_size
= size
;
71 vst
->codec
->extradata
= av_malloc(size
);
72 get_buffer(pb
, vst
->codec
->extradata
, size
);
80 size
= PKTSIZE(get_le32(pb
));
83 get_le32(pb
); // version
85 vst
->codec
->codec_tag
= get_le32(pb
);
86 vst
->codec
->codec_id
=
87 codec_get_id(codec_bmp_tags
, vst
->codec
->codec_tag
);
88 if (vst
->codec
->codec_tag
== MKTAG('R', 'J', 'P', 'G'))
89 vst
->codec
->codec_id
= CODEC_ID_NUV
;
94 ast
->codec
->codec_tag
= get_le32(pb
);
95 ast
->codec
->sample_rate
= get_le32(pb
);
96 ast
->codec
->bits_per_sample
= get_le32(pb
);
97 ast
->codec
->channels
= get_le32(pb
);
98 ast
->codec
->codec_id
=
99 wav_codec_get_id(ast
->codec
->codec_tag
,
100 ast
->codec
->bits_per_sample
);
101 ast
->need_parsing
= AVSTREAM_PARSE_FULL
;
103 url_fskip(pb
, 4 * 4);
113 size
= PKTSIZE(get_le32(pb
));
121 static int nuv_header(AVFormatContext
*s
, AVFormatParameters
*ap
) {
122 NUVContext
*ctx
= s
->priv_data
;
123 ByteIOContext
*pb
= s
->pb
;
124 char id_string
[12], version_string
[5];
126 int is_mythtv
, width
, height
, v_packs
, a_packs
;
128 AVStream
*vst
= NULL
, *ast
= NULL
;
129 get_buffer(pb
, id_string
, 12);
130 is_mythtv
= !memcmp(id_string
, "MythTVVideo", 12);
131 get_buffer(pb
, version_string
, 5);
132 url_fskip(pb
, 3); // padding
133 width
= get_le32(pb
);
134 height
= get_le32(pb
);
135 get_le32(pb
); // unused, "desiredwidth"
136 get_le32(pb
); // unused, "desiredheight"
137 get_byte(pb
); // 'P' == progressive, 'I' == interlaced
138 url_fskip(pb
, 3); // padding
139 aspect
= av_int2dbl(get_le64(pb
));
140 fps
= av_int2dbl(get_le64(pb
));
142 // number of packets per stream type, -1 means unknown, e.g. streaming
143 v_packs
= get_le32(pb
);
144 a_packs
= get_le32(pb
);
145 get_le32(pb
); // text
147 get_le32(pb
); // keyframe distance (?)
150 ctx
->v_id
= stream_nr
++;
151 vst
= av_new_stream(s
, ctx
->v_id
);
152 vst
->codec
->codec_type
= CODEC_TYPE_VIDEO
;
153 vst
->codec
->codec_id
= CODEC_ID_NUV
;
154 vst
->codec
->width
= width
;
155 vst
->codec
->height
= height
;
156 vst
->codec
->bits_per_sample
= 10;
157 vst
->codec
->sample_aspect_ratio
= av_d2q(aspect
, 10000);
158 vst
->r_frame_rate
= av_d2q(fps
, 60000);
159 av_set_pts_info(vst
, 32, 1, 1000);
164 ctx
->a_id
= stream_nr
++;
165 ast
= av_new_stream(s
, ctx
->a_id
);
166 ast
->codec
->codec_type
= CODEC_TYPE_AUDIO
;
167 ast
->codec
->codec_id
= CODEC_ID_PCM_S16LE
;
168 ast
->codec
->channels
= 2;
169 ast
->codec
->sample_rate
= 44100;
170 ast
->codec
->bit_rate
= 2 * 2 * 44100 * 8;
171 ast
->codec
->block_align
= 2 * 2;
172 ast
->codec
->bits_per_sample
= 16;
173 av_set_pts_info(ast
, 32, 1, 1000);
177 get_codec_data(pb
, vst
, ast
, is_mythtv
);
178 ctx
->rtjpg_video
= vst
->codec
->codec_id
== CODEC_ID_NUV
;
184 static int nuv_packet(AVFormatContext
*s
, AVPacket
*pkt
) {
185 NUVContext
*ctx
= s
->priv_data
;
186 ByteIOContext
*pb
= s
->pb
;
187 uint8_t hdr
[HDRSIZE
];
188 frametype_t frametype
;
190 while (!url_feof(pb
)) {
191 int copyhdrsize
= ctx
->rtjpg_video
? HDRSIZE
: 0;
192 ret
= get_buffer(pb
, hdr
, HDRSIZE
);
194 return ret
? ret
: -1;
196 size
= PKTSIZE(AV_RL32(&hdr
[8]));
199 if (!ctx
->rtjpg_video
) {
205 av_log(s
, AV_LOG_ERROR
, "Video packet in file without video stream!\n");
209 ret
= av_new_packet(pkt
, copyhdrsize
+ size
);
212 pkt
->pos
= url_ftell(pb
) - copyhdrsize
;
213 pkt
->pts
= AV_RL32(&hdr
[4]);
214 pkt
->stream_index
= ctx
->v_id
;
215 memcpy(pkt
->data
, hdr
, copyhdrsize
);
216 ret
= get_buffer(pb
, pkt
->data
+ copyhdrsize
, size
);
220 av_log(s
, AV_LOG_ERROR
, "Audio packet in file without audio stream!\n");
224 ret
= av_get_packet(pb
, pkt
, size
);
225 pkt
->pts
= AV_RL32(&hdr
[4]);
226 pkt
->stream_index
= ctx
->a_id
;
229 // contains no data, size value is invalid
239 AVInputFormat nuv_demuxer
= {
241 "NuppelVideo format",