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 "avformat.h" 24#include "internal.h" 25#include "avio_internal.h" 26#include "rawdec.h" 27#include "libavutil/opt.h" 28#include "libavutil/parseutils.h" 29#include "libavutil/pixdesc.h" 30#include "libavutil/avassert.h" 31#include "libavutil/intreadwrite.h" 32 33#define RAW_PACKET_SIZE 1024 34 35int ff_raw_read_partial_packet(AVFormatContext *s, AVPacket *pkt) 36{ 37 int ret, size; 38 39 size = RAW_PACKET_SIZE; 40 41 if (av_new_packet(pkt, size) < 0) 42 return AVERROR(ENOMEM); 43 44 pkt->pos= avio_tell(s->pb); 45 pkt->stream_index = 0; 46 ret = ffio_read_partial(s->pb, pkt->data, size); 47 if (ret < 0) { 48 av_free_packet(pkt); 49 return ret; 50 } 51 av_shrink_packet(pkt, ret); 52 return ret; 53} 54 55int ff_raw_audio_read_header(AVFormatContext *s) 56{ 57 AVStream *st = avformat_new_stream(s, NULL); 58 if (!st) 59 return AVERROR(ENOMEM); 60 st->codec->codec_type = AVMEDIA_TYPE_AUDIO; 61 st->codec->codec_id = s->iformat->raw_codec_id; 62 st->need_parsing = AVSTREAM_PARSE_FULL_RAW; 63 st->start_time = 0; 64 /* the parameters will be extracted from the compressed bitstream */ 65 66 return 0; 67} 68 69/* MPEG-1/H.263 input */ 70int ff_raw_video_read_header(AVFormatContext *s) 71{ 72 AVStream *st; 73 FFRawVideoDemuxerContext *s1 = s->priv_data; 74 int ret = 0; 75 76 77 st = avformat_new_stream(s, NULL); 78 if (!st) { 79 ret = AVERROR(ENOMEM); 80 goto fail; 81 } 82 83 st->codec->codec_type = AVMEDIA_TYPE_VIDEO; 84 st->codec->codec_id = s->iformat->raw_codec_id; 85 st->need_parsing = AVSTREAM_PARSE_FULL_RAW; 86 87 st->codec->time_base = av_inv_q(s1->framerate); 88 avpriv_set_pts_info(st, 64, 1, 1200000); 89 90fail: 91 return ret; 92} 93 94static int ff_raw_data_read_header(AVFormatContext *s) 95{ 96 AVStream *st = avformat_new_stream(s, NULL); 97 if (!st) 98 return AVERROR(ENOMEM); 99 st->codec->codec_type = AVMEDIA_TYPE_DATA; 100 st->codec->codec_id = s->iformat->raw_codec_id; 101 st->start_time = 0; 102 return 0; 103} 104 105/* Note: Do not forget to add new entries to the Makefile as well. */ 106 107#define OFFSET(x) offsetof(FFRawVideoDemuxerContext, x) 108#define DEC AV_OPT_FLAG_DECODING_PARAM 109const AVOption ff_rawvideo_options[] = { 110 { "framerate", "", OFFSET(framerate), AV_OPT_TYPE_VIDEO_RATE, {.str = "25"}, 0, 0, DEC}, 111 { NULL }, 112}; 113 114#if CONFIG_DATA_DEMUXER 115AVInputFormat ff_data_demuxer = { 116 .name = "data", 117 .long_name = NULL_IF_CONFIG_SMALL("raw data"), 118 .read_header = ff_raw_data_read_header, 119 .read_packet = ff_raw_read_partial_packet, 120 .raw_codec_id = AV_CODEC_ID_NONE, 121}; 122#endif 123 124#if CONFIG_LATM_DEMUXER 125 126AVInputFormat ff_latm_demuxer = { 127 .name = "latm", 128 .long_name = NULL_IF_CONFIG_SMALL("raw LOAS/LATM"), 129 .read_header = ff_raw_audio_read_header, 130 .read_packet = ff_raw_read_partial_packet, 131 .flags = AVFMT_GENERIC_INDEX, 132 .extensions = "latm", 133 .raw_codec_id = AV_CODEC_ID_AAC_LATM, 134}; 135#endif 136 137#if CONFIG_MJPEG_DEMUXER 138static int mjpeg_probe(AVProbeData *p) 139{ 140 int i; 141 int state = -1; 142 int nb_invalid = 0; 143 int nb_frames = 0; 144 145 for (i=0; i<p->buf_size-2; i++) { 146 int c; 147 if (p->buf[i] != 0xFF) 148 continue; 149 c = p->buf[i+1]; 150 switch (c) { 151 case 0xD8: 152 state = 0xD8; 153 break; 154 case 0xC0: 155 case 0xC1: 156 case 0xC2: 157 case 0xC3: 158 case 0xC5: 159 case 0xC6: 160 case 0xC7: 161 case 0xF7: 162 if (state == 0xD8) { 163 state = 0xC0; 164 } else 165 nb_invalid++; 166 break; 167 case 0xDA: 168 if (state == 0xC0) { 169 state = 0xDA; 170 } else 171 nb_invalid++; 172 break; 173 case 0xD9: 174 if (state == 0xDA) { 175 state = 0xD9; 176 nb_frames++; 177 } else 178 nb_invalid++; 179 break; 180 default: 181 if ( (c >= 0x02 && c <= 0xBF) 182 || c == 0xC8) { 183 nb_invalid++; 184 } 185 } 186 } 187 188 if (nb_invalid*4 + 1 < nb_frames) { 189 static const char ct_jpeg[] = "\r\nContent-Type: image/jpeg\r\n\r\n"; 190 int i; 191 192 for (i=0; i<FFMIN(p->buf_size - sizeof(ct_jpeg), 100); i++) 193 if (!memcmp(p->buf + i, ct_jpeg, sizeof(ct_jpeg) - 1)) 194 return AVPROBE_SCORE_EXTENSION; 195 196 if (nb_invalid == 0 && nb_frames > 2) 197 return AVPROBE_SCORE_EXTENSION / 2; 198 return AVPROBE_SCORE_EXTENSION / 4; 199 } 200 201 return 0; 202} 203 204FF_DEF_RAWVIDEO_DEMUXER2(mjpeg, "raw MJPEG video", mjpeg_probe, "mjpg,mjpeg,mpo", AV_CODEC_ID_MJPEG, AVFMT_GENERIC_INDEX|AVFMT_NOTIMESTAMPS) 205#endif 206 207#if CONFIG_MLP_DEMUXER 208AVInputFormat ff_mlp_demuxer = { 209 .name = "mlp", 210 .long_name = NULL_IF_CONFIG_SMALL("raw MLP"), 211 .read_header = ff_raw_audio_read_header, 212 .read_packet = ff_raw_read_partial_packet, 213 .flags = AVFMT_GENERIC_INDEX, 214 .extensions = "mlp", 215 .raw_codec_id = AV_CODEC_ID_MLP, 216}; 217#endif 218 219#if CONFIG_TRUEHD_DEMUXER 220AVInputFormat ff_truehd_demuxer = { 221 .name = "truehd", 222 .long_name = NULL_IF_CONFIG_SMALL("raw TrueHD"), 223 .read_header = ff_raw_audio_read_header, 224 .read_packet = ff_raw_read_partial_packet, 225 .flags = AVFMT_GENERIC_INDEX, 226 .extensions = "thd", 227 .raw_codec_id = AV_CODEC_ID_TRUEHD, 228}; 229#endif 230 231#if CONFIG_SHORTEN_DEMUXER 232AVInputFormat ff_shorten_demuxer = { 233 .name = "shn", 234 .long_name = NULL_IF_CONFIG_SMALL("raw Shorten"), 235 .read_header = ff_raw_audio_read_header, 236 .read_packet = ff_raw_read_partial_packet, 237 .flags = AVFMT_NOBINSEARCH | AVFMT_NOGENSEARCH | AVFMT_NO_BYTE_SEEK, 238 .extensions = "shn", 239 .raw_codec_id = AV_CODEC_ID_SHORTEN, 240}; 241#endif 242 243#if CONFIG_VC1_DEMUXER 244FF_DEF_RAWVIDEO_DEMUXER2(vc1, "raw VC-1", NULL, "vc1", AV_CODEC_ID_VC1, AVFMT_GENERIC_INDEX|AVFMT_NOTIMESTAMPS) 245#endif 246