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
);
153 return AVERROR(ENOMEM
);
154 vst
->codec
->codec_type
= CODEC_TYPE_VIDEO
;
155 vst
->codec
->codec_id
= CODEC_ID_NUV
;
156 vst
->codec
->width
= width
;
157 vst
->codec
->height
= height
;
158 vst
->codec
->bits_per_sample
= 10;
159 vst
->codec
->sample_aspect_ratio
= av_d2q(aspect
, 10000);
160 vst
->r_frame_rate
= av_d2q(fps
, 60000);
161 av_set_pts_info(vst
, 32, 1, 1000);
166 ctx
->a_id
= stream_nr
++;
167 ast
= av_new_stream(s
, ctx
->a_id
);
169 return AVERROR(ENOMEM
);
170 ast
->codec
->codec_type
= CODEC_TYPE_AUDIO
;
171 ast
->codec
->codec_id
= CODEC_ID_PCM_S16LE
;
172 ast
->codec
->channels
= 2;
173 ast
->codec
->sample_rate
= 44100;
174 ast
->codec
->bit_rate
= 2 * 2 * 44100 * 8;
175 ast
->codec
->block_align
= 2 * 2;
176 ast
->codec
->bits_per_sample
= 16;
177 av_set_pts_info(ast
, 32, 1, 1000);
181 get_codec_data(pb
, vst
, ast
, is_mythtv
);
182 ctx
->rtjpg_video
= vst
->codec
->codec_id
== CODEC_ID_NUV
;
188 static int nuv_packet(AVFormatContext
*s
, AVPacket
*pkt
) {
189 NUVContext
*ctx
= s
->priv_data
;
190 ByteIOContext
*pb
= s
->pb
;
191 uint8_t hdr
[HDRSIZE
];
192 frametype_t frametype
;
194 while (!url_feof(pb
)) {
195 int copyhdrsize
= ctx
->rtjpg_video
? HDRSIZE
: 0;
196 ret
= get_buffer(pb
, hdr
, HDRSIZE
);
198 return ret
? ret
: -1;
200 size
= PKTSIZE(AV_RL32(&hdr
[8]));
203 if (!ctx
->rtjpg_video
) {
209 av_log(s
, AV_LOG_ERROR
, "Video packet in file without video stream!\n");
213 ret
= av_new_packet(pkt
, copyhdrsize
+ size
);
216 pkt
->pos
= url_ftell(pb
) - copyhdrsize
;
217 pkt
->pts
= AV_RL32(&hdr
[4]);
218 pkt
->stream_index
= ctx
->v_id
;
219 memcpy(pkt
->data
, hdr
, copyhdrsize
);
220 ret
= get_buffer(pb
, pkt
->data
+ copyhdrsize
, size
);
224 av_log(s
, AV_LOG_ERROR
, "Audio packet in file without audio stream!\n");
228 ret
= av_get_packet(pb
, pkt
, size
);
229 pkt
->pts
= AV_RL32(&hdr
[4]);
230 pkt
->stream_index
= ctx
->a_id
;
233 // contains no data, size value is invalid
243 AVInputFormat nuv_demuxer
= {
245 NULL_IF_CONFIG_SMALL("NuppelVideo format"),