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
22 #include "libavutil/intreadwrite.h"
40 static int nuv_probe(AVProbeData
*p
) {
41 if (!memcmp(p
->buf
, "NuppelVideo", 12))
42 return AVPROBE_SCORE_MAX
;
43 if (!memcmp(p
->buf
, "MythTVVideo", 12))
44 return AVPROBE_SCORE_MAX
;
48 //! little macro to sanitize packet size
49 #define PKTSIZE(s) (s & 0xffffff)
52 * \brief read until we found all data needed for decoding
53 * \param vst video stream of which to change parameters
54 * \param ast video stream of which to change parameters
55 * \param myth set if this is a MythTVVideo format file
56 * \return 1 if all required codec data was found
58 static int get_codec_data(ByteIOContext
*pb
, AVStream
*vst
,
59 AVStream
*ast
, int myth
) {
60 nuv_frametype frametype
;
62 return 1; // no codec data needed
63 while (!url_feof(pb
)) {
65 frametype
= get_byte(pb
);
68 subtype
= get_byte(pb
);
70 size
= PKTSIZE(get_le32(pb
));
71 if (vst
&& subtype
== 'R') {
72 vst
->codec
->extradata_size
= size
;
73 vst
->codec
->extradata
= av_malloc(size
);
74 get_buffer(pb
, vst
->codec
->extradata
, size
);
82 size
= PKTSIZE(get_le32(pb
));
85 get_le32(pb
); // version
87 vst
->codec
->codec_tag
= get_le32(pb
);
88 vst
->codec
->codec_id
=
89 codec_get_id(codec_bmp_tags
, vst
->codec
->codec_tag
);
90 if (vst
->codec
->codec_tag
== MKTAG('R', 'J', 'P', 'G'))
91 vst
->codec
->codec_id
= CODEC_ID_NUV
;
96 ast
->codec
->codec_tag
= get_le32(pb
);
97 ast
->codec
->sample_rate
= get_le32(pb
);
98 ast
->codec
->bits_per_coded_sample
= get_le32(pb
);
99 ast
->codec
->channels
= get_le32(pb
);
100 ast
->codec
->codec_id
=
101 wav_codec_get_id(ast
->codec
->codec_tag
,
102 ast
->codec
->bits_per_coded_sample
);
103 ast
->need_parsing
= AVSTREAM_PARSE_FULL
;
105 url_fskip(pb
, 4 * 4);
115 size
= PKTSIZE(get_le32(pb
));
123 static int nuv_header(AVFormatContext
*s
, AVFormatParameters
*ap
) {
124 NUVContext
*ctx
= s
->priv_data
;
125 ByteIOContext
*pb
= s
->pb
;
126 char id_string
[12], version_string
[5];
128 int is_mythtv
, width
, height
, v_packs
, a_packs
;
130 AVStream
*vst
= NULL
, *ast
= NULL
;
131 get_buffer(pb
, id_string
, 12);
132 is_mythtv
= !memcmp(id_string
, "MythTVVideo", 12);
133 get_buffer(pb
, version_string
, 5);
134 url_fskip(pb
, 3); // padding
135 width
= get_le32(pb
);
136 height
= get_le32(pb
);
137 get_le32(pb
); // unused, "desiredwidth"
138 get_le32(pb
); // unused, "desiredheight"
139 get_byte(pb
); // 'P' == progressive, 'I' == interlaced
140 url_fskip(pb
, 3); // padding
141 aspect
= av_int2dbl(get_le64(pb
));
142 if (aspect
> 0.9999 && aspect
< 1.0001)
144 fps
= av_int2dbl(get_le64(pb
));
146 // number of packets per stream type, -1 means unknown, e.g. streaming
147 v_packs
= get_le32(pb
);
148 a_packs
= get_le32(pb
);
149 get_le32(pb
); // text
151 get_le32(pb
); // keyframe distance (?)
154 ctx
->v_id
= stream_nr
++;
155 vst
= av_new_stream(s
, ctx
->v_id
);
157 return AVERROR(ENOMEM
);
158 vst
->codec
->codec_type
= CODEC_TYPE_VIDEO
;
159 vst
->codec
->codec_id
= CODEC_ID_NUV
;
160 vst
->codec
->width
= width
;
161 vst
->codec
->height
= height
;
162 vst
->codec
->bits_per_coded_sample
= 10;
163 vst
->sample_aspect_ratio
= av_d2q(aspect
* height
/ width
, 10000);
164 vst
->r_frame_rate
= av_d2q(fps
, 60000);
165 av_set_pts_info(vst
, 32, 1, 1000);
170 ctx
->a_id
= stream_nr
++;
171 ast
= av_new_stream(s
, ctx
->a_id
);
173 return AVERROR(ENOMEM
);
174 ast
->codec
->codec_type
= CODEC_TYPE_AUDIO
;
175 ast
->codec
->codec_id
= CODEC_ID_PCM_S16LE
;
176 ast
->codec
->channels
= 2;
177 ast
->codec
->sample_rate
= 44100;
178 ast
->codec
->bit_rate
= 2 * 2 * 44100 * 8;
179 ast
->codec
->block_align
= 2 * 2;
180 ast
->codec
->bits_per_coded_sample
= 16;
181 av_set_pts_info(ast
, 32, 1, 1000);
185 get_codec_data(pb
, vst
, ast
, is_mythtv
);
186 ctx
->rtjpg_video
= vst
&& vst
->codec
->codec_id
== CODEC_ID_NUV
;
192 static int nuv_packet(AVFormatContext
*s
, AVPacket
*pkt
) {
193 NUVContext
*ctx
= s
->priv_data
;
194 ByteIOContext
*pb
= s
->pb
;
195 uint8_t hdr
[HDRSIZE
];
196 nuv_frametype frametype
;
198 while (!url_feof(pb
)) {
199 int copyhdrsize
= ctx
->rtjpg_video
? HDRSIZE
: 0;
200 ret
= get_buffer(pb
, hdr
, HDRSIZE
);
202 return ret
? ret
: -1;
204 size
= PKTSIZE(AV_RL32(&hdr
[8]));
207 if (!ctx
->rtjpg_video
) {
213 av_log(s
, AV_LOG_ERROR
, "Video packet in file without video stream!\n");
217 ret
= av_new_packet(pkt
, copyhdrsize
+ size
);
220 pkt
->pos
= url_ftell(pb
) - copyhdrsize
;
221 pkt
->pts
= AV_RL32(&hdr
[4]);
222 pkt
->stream_index
= ctx
->v_id
;
223 memcpy(pkt
->data
, hdr
, copyhdrsize
);
224 ret
= get_buffer(pb
, pkt
->data
+ copyhdrsize
, size
);
228 av_log(s
, AV_LOG_ERROR
, "Audio packet in file without audio stream!\n");
232 ret
= av_get_packet(pb
, pkt
, size
);
233 pkt
->pts
= AV_RL32(&hdr
[4]);
234 pkt
->stream_index
= ctx
->a_id
;
237 // contains no data, size value is invalid
247 AVInputFormat nuv_demuxer
= {
249 NULL_IF_CONFIG_SMALL("NuppelVideo format"),