Mercurial > libavformat.hg
annotate pva.c @ 2908:9b7f5c62b4ee libavformat
remove unnecessary check
author | ivo |
---|---|
date | Mon, 07 Jan 2008 23:39:47 +0000 |
parents | b548dfced05b |
children | 840ade0be043 |
rev | line source |
---|---|
2880 | 1 /* |
2 * TechnoTrend PVA (.pva) demuxer | |
3 * Copyright (c) 2007, 2008 Ivo van Poorten | |
4 * | |
5 * This file is part of FFmpeg. | |
6 * | |
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. | |
11 * | |
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. | |
16 * | |
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 | |
20 */ | |
21 | |
22 #include "avformat.h" | |
2907
b548dfced05b
use ff_parse_pes_pts for parsing an MPEG-PES timestamp
ivo
parents:
2900
diff
changeset
|
23 #include "mpeg.h" |
2880 | 24 |
25 #define PVA_MAX_PAYLOAD_LENGTH 0x17f8 | |
26 #define PVA_VIDEO_PAYLOAD 0x01 | |
27 #define PVA_AUDIO_PAYLOAD 0x02 | |
28 #define PVA_MAGIC (('A' << 8) + 'V') | |
29 | |
30 typedef struct { | |
31 int continue_pes; | |
32 } PVAContext; | |
33 | |
34 static int pva_probe(AVProbeData * pd) { | |
35 unsigned char *buf = pd->buf; | |
36 | |
37 if (AV_RB16(buf) == PVA_MAGIC && buf[2] && buf[2] < 3 && buf[4] == 0x55) | |
38 return AVPROBE_SCORE_MAX / 2; | |
39 | |
40 return 0; | |
41 } | |
42 | |
43 static int pva_read_header(AVFormatContext *s, AVFormatParameters *ap) { | |
44 AVStream *st; | |
45 | |
46 if (!(st = av_new_stream(s, 0))) | |
47 return AVERROR(ENOMEM); | |
48 st->codec->codec_type = CODEC_TYPE_VIDEO; | |
49 st->codec->codec_id = CODEC_ID_MPEG2VIDEO; | |
50 st->need_parsing = AVSTREAM_PARSE_FULL; | |
51 av_set_pts_info(st, 32, 1, 90000); | |
52 | |
53 if (!(st = av_new_stream(s, 1))) | |
54 return AVERROR(ENOMEM); | |
55 st->codec->codec_type = CODEC_TYPE_AUDIO; | |
2896 | 56 st->codec->codec_id = CODEC_ID_MP2; |
2880 | 57 st->need_parsing = AVSTREAM_PARSE_HEADERS; |
58 av_set_pts_info(st, 33, 1, 90000); | |
59 | |
60 /* the parameters will be extracted from the compressed bitstream */ | |
61 return 0; | |
62 } | |
63 | |
64 static int pva_read_packet(AVFormatContext *s, AVPacket *pkt) { | |
65 ByteIOContext *pb = s->pb; | |
66 PVAContext *pvactx = s->priv_data; | |
67 int ret, syncword, streamid, reserved, flags, length, pts_flag; | |
2895 | 68 int64_t pva_pts = AV_NOPTS_VALUE; |
2880 | 69 |
2898
32895d361262
do not return an error, but warn and recover when encountering an audio packet
ivo
parents:
2897
diff
changeset
|
70 recover: |
2880 | 71 syncword = get_be16(pb); |
72 streamid = get_byte(pb); | |
73 get_byte(pb); /* counter not used */ | |
74 reserved = get_byte(pb); | |
75 flags = get_byte(pb); | |
76 length = get_be16(pb); | |
77 | |
2900 | 78 pts_flag = flags & 0x10; |
2880 | 79 |
80 if (syncword != PVA_MAGIC) { | |
81 av_log(s, AV_LOG_ERROR, "invalid syncword\n"); | |
82 return AVERROR(EIO); | |
83 } | |
2897 | 84 if (streamid != PVA_VIDEO_PAYLOAD && streamid != PVA_AUDIO_PAYLOAD) { |
85 av_log(s, AV_LOG_ERROR, "invalid streamid\n"); | |
86 return AVERROR(EIO); | |
87 } | |
2880 | 88 if (reserved != 0x55) { |
89 av_log(s, AV_LOG_WARNING, "expected reserved byte to be 0x55\n"); | |
90 } | |
91 if (length > PVA_MAX_PAYLOAD_LENGTH) { | |
92 av_log(s, AV_LOG_ERROR, "invalid payload length %u\n", length); | |
93 return AVERROR(EIO); | |
94 } | |
95 | |
96 if (streamid == PVA_VIDEO_PAYLOAD && pts_flag) { | |
97 pva_pts = get_be32(pb); | |
98 length -= 4; | |
99 } else if (streamid == PVA_AUDIO_PAYLOAD) { | |
100 /* PVA Audio Packets either start with a signaled PES packet or | |
101 * are a continuation of the previous PES packet. New PES packets | |
102 * always start at the beginning of a PVA Packet, never somewhere in | |
103 * the middle. */ | |
104 if (!pvactx->continue_pes) { | |
105 int pes_signal, pes_header_data_length, pes_packet_length, | |
106 pes_flags; | |
107 unsigned char pes_header_data[256]; | |
108 | |
109 pes_signal = get_be24(pb); | |
110 get_byte(pb); | |
111 pes_packet_length = get_be16(pb); | |
112 pes_flags = get_be16(pb); | |
113 pes_header_data_length = get_byte(pb); | |
114 | |
115 if (pes_signal != 1) { | |
2898
32895d361262
do not return an error, but warn and recover when encountering an audio packet
ivo
parents:
2897
diff
changeset
|
116 av_log(s, AV_LOG_WARNING, "expected signaled PES packet, " |
32895d361262
do not return an error, but warn and recover when encountering an audio packet
ivo
parents:
2897
diff
changeset
|
117 "trying to recover\n"); |
32895d361262
do not return an error, but warn and recover when encountering an audio packet
ivo
parents:
2897
diff
changeset
|
118 url_fskip(pb, length - 9); |
32895d361262
do not return an error, but warn and recover when encountering an audio packet
ivo
parents:
2897
diff
changeset
|
119 goto recover; |
2880 | 120 } |
121 | |
122 get_buffer(pb, pes_header_data, pes_header_data_length); | |
123 length -= 9 + pes_header_data_length; | |
124 | |
125 pes_packet_length -= 3 + pes_header_data_length; | |
126 | |
127 pvactx->continue_pes = pes_packet_length; | |
128 | |
2907
b548dfced05b
use ff_parse_pes_pts for parsing an MPEG-PES timestamp
ivo
parents:
2900
diff
changeset
|
129 if (pes_flags & 0x80 && (pes_header_data[0] & 0xf0) == 0x20) |
b548dfced05b
use ff_parse_pes_pts for parsing an MPEG-PES timestamp
ivo
parents:
2900
diff
changeset
|
130 pva_pts = ff_parse_pes_pts(pes_header_data); |
2880 | 131 } |
132 | |
133 pvactx->continue_pes -= length; | |
134 | |
135 if (pvactx->continue_pes < 0) { | |
136 av_log(s, AV_LOG_WARNING, "audio data corruption\n"); | |
137 pvactx->continue_pes = 0; | |
138 } | |
139 } | |
140 | |
141 if ((ret = av_get_packet(pb, pkt, length)) <= 0) | |
142 return AVERROR(EIO); | |
143 | |
144 pkt->stream_index = streamid - 1; | |
145 pkt->pts = pva_pts; | |
146 | |
147 return ret; | |
148 } | |
149 | |
150 AVInputFormat pva_demuxer = { | |
151 "pva", | |
152 "pva file and stream format", | |
153 sizeof(PVAContext), | |
154 pva_probe, | |
155 pva_read_header, | |
156 pva_read_packet, | |
157 }; |