• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * RAW demuxers
3  * Copyright (c) 2001 Fabrice Bellard
4  * Copyright (c) 2005 Alex Beregszaszi
5  *
6  * This file is part of FFmpeg.
7  *
8  * FFmpeg is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2.1 of the License, or (at your option) any later version.
12  *
13  * FFmpeg is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with FFmpeg; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21  */
22 
23 #include "config_components.h"
24 
25 #include "avformat.h"
26 #include "internal.h"
27 #include "avio_internal.h"
28 #include "rawdec.h"
29 #include "libavutil/opt.h"
30 #include "libavutil/parseutils.h"
31 #include "libavutil/pixdesc.h"
32 #include "libavutil/intreadwrite.h"
33 
34 #define RAW_PACKET_SIZE 1024
35 
ff_raw_read_partial_packet(AVFormatContext * s,AVPacket * pkt)36 int ff_raw_read_partial_packet(AVFormatContext *s, AVPacket *pkt)
37 {
38     FFRawDemuxerContext *raw = s->priv_data;
39     int ret, size;
40 
41     size = raw->raw_packet_size;
42 
43     if ((ret = av_new_packet(pkt, size)) < 0)
44         return ret;
45 
46     pkt->pos= avio_tell(s->pb);
47     pkt->stream_index = 0;
48     ret = avio_read_partial(s->pb, pkt->data, size);
49     if (ret < 0) {
50         av_packet_unref(pkt);
51         return ret;
52     }
53     av_shrink_packet(pkt, ret);
54     return ret;
55 }
56 
ff_raw_audio_read_header(AVFormatContext * s)57 int ff_raw_audio_read_header(AVFormatContext *s)
58 {
59     AVStream *st = avformat_new_stream(s, NULL);
60     if (!st)
61         return AVERROR(ENOMEM);
62     st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
63     st->codecpar->codec_id = s->iformat->raw_codec_id;
64     ffstream(st)->need_parsing = AVSTREAM_PARSE_FULL_RAW;
65     st->start_time = 0;
66     /* the parameters will be extracted from the compressed bitstream */
67 
68     return 0;
69 }
70 
71 /* MPEG-1/H.263 input */
ff_raw_video_read_header(AVFormatContext * s)72 int ff_raw_video_read_header(AVFormatContext *s)
73 {
74     AVStream *st;
75     FFStream *sti;
76     FFRawVideoDemuxerContext *s1 = s->priv_data;
77     int ret = 0;
78 
79 
80     st = avformat_new_stream(s, NULL);
81     if (!st) {
82         ret = AVERROR(ENOMEM);
83         goto fail;
84     }
85     sti = ffstream(st);
86 
87     st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
88     st->codecpar->codec_id = s->iformat->raw_codec_id;
89     sti->need_parsing = AVSTREAM_PARSE_FULL_RAW;
90 
91     sti->avctx->framerate = s1->framerate;
92     avpriv_set_pts_info(st, 64, 1, 1200000);
93 
94 fail:
95     return ret;
96 }
97 
ff_raw_subtitle_read_header(AVFormatContext * s)98 int ff_raw_subtitle_read_header(AVFormatContext *s)
99 {
100     AVStream *st = avformat_new_stream(s, NULL);
101     if (!st)
102         return AVERROR(ENOMEM);
103     st->codecpar->codec_type = AVMEDIA_TYPE_SUBTITLE;
104     st->codecpar->codec_id = s->iformat->raw_codec_id;
105     st->start_time = 0;
106     return 0;
107 }
108 
raw_data_read_header(AVFormatContext * s)109 static int raw_data_read_header(AVFormatContext *s)
110 {
111     AVStream *st = avformat_new_stream(s, NULL);
112     if (!st)
113         return AVERROR(ENOMEM);
114     st->codecpar->codec_type = AVMEDIA_TYPE_DATA;
115     st->codecpar->codec_id = s->iformat->raw_codec_id;
116     st->start_time = 0;
117     return 0;
118 }
119 
120 /* Note: Do not forget to add new entries to the Makefile as well. */
121 
122 #define OFFSET(x) offsetof(FFRawVideoDemuxerContext, x)
123 #define DEC AV_OPT_FLAG_DECODING_PARAM
124 static const AVOption rawvideo_options[] = {
125     { "framerate", "", OFFSET(framerate), AV_OPT_TYPE_VIDEO_RATE, {.str = "25"}, 0, INT_MAX, DEC},
126     { "raw_packet_size", "", OFFSET(raw_packet_size), AV_OPT_TYPE_INT, {.i64 = RAW_PACKET_SIZE }, 1, INT_MAX, DEC},
127     { NULL },
128 };
129 #undef OFFSET
130 
131 const AVClass ff_rawvideo_demuxer_class = {
132     .class_name = "generic raw video demuxer",
133     .item_name  = av_default_item_name,
134     .option     = rawvideo_options,
135     .version    = LIBAVUTIL_VERSION_INT,
136 };
137 
138 #define OFFSET(x) offsetof(FFRawDemuxerContext, x)
139 const AVOption ff_raw_options[] = {
140     { "raw_packet_size", "", OFFSET(raw_packet_size), AV_OPT_TYPE_INT, {.i64 = RAW_PACKET_SIZE }, 1, INT_MAX, DEC},
141     { NULL },
142 };
143 
144 const AVClass ff_raw_demuxer_class = {
145     .class_name = "generic raw demuxer",
146     .item_name  = av_default_item_name,
147     .option     = ff_raw_options,
148     .version    = LIBAVUTIL_VERSION_INT,
149 };
150 
151 #if CONFIG_DATA_DEMUXER
152 const AVInputFormat ff_data_demuxer = {
153     .name           = "data",
154     .long_name      = NULL_IF_CONFIG_SMALL("raw data"),
155     .read_header    = raw_data_read_header,
156     .read_packet    = ff_raw_read_partial_packet,
157     .raw_codec_id   = AV_CODEC_ID_NONE,
158     .flags          = AVFMT_NOTIMESTAMPS,
159     .priv_data_size = sizeof(FFRawDemuxerContext),\
160     .priv_class     = &ff_raw_demuxer_class,
161 };
162 #endif
163 
164 #if CONFIG_MJPEG_DEMUXER
mjpeg_probe(const AVProbeData * p)165 static int mjpeg_probe(const AVProbeData *p)
166 {
167     int i;
168     int state = -1;
169     int nb_invalid = 0;
170     int nb_frames = 0;
171 
172     for (i = 0; i < p->buf_size - 1; i++) {
173         int c;
174         if (p->buf[i] != 0xFF)
175             continue;
176         c = p->buf[i+1];
177         switch (c) {
178         case 0xD8:
179             state = 0xD8;
180             break;
181         case 0xC0:
182         case 0xC1:
183         case 0xC2:
184         case 0xC3:
185         case 0xC5:
186         case 0xC6:
187         case 0xC7:
188         case 0xF7:
189             if (state == 0xD8) {
190                 state = 0xC0;
191             } else
192                 nb_invalid++;
193             break;
194         case 0xDA:
195             if (state == 0xC0) {
196                 state = 0xDA;
197             } else
198                 nb_invalid++;
199             break;
200         case 0xD9:
201             if (state == 0xDA) {
202                 state = 0xD9;
203                 nb_frames++;
204             } else
205                 nb_invalid++;
206             break;
207         default:
208             if (  (c >= 0x02 && c <= 0xBF)
209                 || c == 0xC8) {
210                 nb_invalid++;
211             }
212         }
213     }
214 
215     if (nb_invalid*4 + 1 < nb_frames) {
216         static const char ct_jpeg[] = "\r\nContent-Type: image/jpeg\r\n";
217         int i;
218 
219         for (i=0; i<FFMIN(p->buf_size - (int)sizeof(ct_jpeg), 100); i++)
220             if (!memcmp(p->buf + i, ct_jpeg, sizeof(ct_jpeg) - 1))
221                 return AVPROBE_SCORE_EXTENSION;
222 
223         if (nb_invalid == 0 && nb_frames > 2)
224             return AVPROBE_SCORE_EXTENSION / 2;
225         return AVPROBE_SCORE_EXTENSION / 4;
226     }
227     if (!nb_invalid && nb_frames)
228         return AVPROBE_SCORE_EXTENSION / 4;
229 
230     return 0;
231 }
232 
233 FF_DEF_RAWVIDEO_DEMUXER2(mjpeg, "raw MJPEG video", mjpeg_probe, "mjpg,mjpeg,mpo", AV_CODEC_ID_MJPEG, AVFMT_GENERIC_INDEX|AVFMT_NOTIMESTAMPS)
234 #endif
235