1cabdff1aSopenharmony_ci/* 2cabdff1aSopenharmony_ci * id Quake II CIN File Demuxer 3cabdff1aSopenharmony_ci * Copyright (c) 2003 The FFmpeg project 4cabdff1aSopenharmony_ci * 5cabdff1aSopenharmony_ci * This file is part of FFmpeg. 6cabdff1aSopenharmony_ci * 7cabdff1aSopenharmony_ci * FFmpeg is free software; you can redistribute it and/or 8cabdff1aSopenharmony_ci * modify it under the terms of the GNU Lesser General Public 9cabdff1aSopenharmony_ci * License as published by the Free Software Foundation; either 10cabdff1aSopenharmony_ci * version 2.1 of the License, or (at your option) any later version. 11cabdff1aSopenharmony_ci * 12cabdff1aSopenharmony_ci * FFmpeg is distributed in the hope that it will be useful, 13cabdff1aSopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of 14cabdff1aSopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15cabdff1aSopenharmony_ci * Lesser General Public License for more details. 16cabdff1aSopenharmony_ci * 17cabdff1aSopenharmony_ci * You should have received a copy of the GNU Lesser General Public 18cabdff1aSopenharmony_ci * License along with FFmpeg; if not, write to the Free Software 19cabdff1aSopenharmony_ci * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 20cabdff1aSopenharmony_ci */ 21cabdff1aSopenharmony_ci 22cabdff1aSopenharmony_ci/** 23cabdff1aSopenharmony_ci * @file 24cabdff1aSopenharmony_ci * id Quake II CIN file demuxer by Mike Melanson (melanson@pcisys.net) 25cabdff1aSopenharmony_ci * For more information about the id CIN format, visit: 26cabdff1aSopenharmony_ci * http://www.csse.monash.edu.au/~timf/ 27cabdff1aSopenharmony_ci * 28cabdff1aSopenharmony_ci * CIN is a somewhat quirky and ill-defined format. Here are some notes 29cabdff1aSopenharmony_ci * for anyone trying to understand the technical details of this format: 30cabdff1aSopenharmony_ci * 31cabdff1aSopenharmony_ci * The format has no definite file signature. This is problematic for a 32cabdff1aSopenharmony_ci * general-purpose media player that wants to automatically detect file 33cabdff1aSopenharmony_ci * types. However, a CIN file does start with 5 32-bit numbers that 34cabdff1aSopenharmony_ci * specify audio and video parameters. This demuxer gets around the lack 35cabdff1aSopenharmony_ci * of file signature by performing sanity checks on those parameters. 36cabdff1aSopenharmony_ci * Probabilistically, this is a reasonable solution since the number of 37cabdff1aSopenharmony_ci * valid combinations of the 5 parameters is a very small subset of the 38cabdff1aSopenharmony_ci * total 160-bit number space. 39cabdff1aSopenharmony_ci * 40cabdff1aSopenharmony_ci * Refer to the function idcin_probe() for the precise A/V parameters 41cabdff1aSopenharmony_ci * that this demuxer allows. 42cabdff1aSopenharmony_ci * 43cabdff1aSopenharmony_ci * Next, each audio and video frame has a duration of 1/14 sec. If the 44cabdff1aSopenharmony_ci * audio sample rate is a multiple of the common frequency 22050 Hz it will 45cabdff1aSopenharmony_ci * divide evenly by 14. However, if the sample rate is 11025 Hz: 46cabdff1aSopenharmony_ci * 11025 (samples/sec) / 14 (frames/sec) = 787.5 (samples/frame) 47cabdff1aSopenharmony_ci * The way the CIN stores audio in this case is by storing 787 sample 48cabdff1aSopenharmony_ci * frames in the first audio frame and 788 sample frames in the second 49cabdff1aSopenharmony_ci * audio frame. Therefore, the total number of bytes in an audio frame 50cabdff1aSopenharmony_ci * is given as: 51cabdff1aSopenharmony_ci * audio frame #0: 787 * (bytes/sample) * (# channels) bytes in frame 52cabdff1aSopenharmony_ci * audio frame #1: 788 * (bytes/sample) * (# channels) bytes in frame 53cabdff1aSopenharmony_ci * audio frame #2: 787 * (bytes/sample) * (# channels) bytes in frame 54cabdff1aSopenharmony_ci * audio frame #3: 788 * (bytes/sample) * (# channels) bytes in frame 55cabdff1aSopenharmony_ci * 56cabdff1aSopenharmony_ci * Finally, not all id CIN creation tools agree on the resolution of the 57cabdff1aSopenharmony_ci * color palette, apparently. Some creation tools specify red, green, and 58cabdff1aSopenharmony_ci * blue palette components in terms of 6-bit VGA color DAC values which 59cabdff1aSopenharmony_ci * range from 0..63. Other tools specify the RGB components as full 8-bit 60cabdff1aSopenharmony_ci * values that range from 0..255. Since there are no markers in the file to 61cabdff1aSopenharmony_ci * differentiate between the two variants, this demuxer uses the following 62cabdff1aSopenharmony_ci * heuristic: 63cabdff1aSopenharmony_ci * - load the 768 palette bytes from disk 64cabdff1aSopenharmony_ci * - assume that they will need to be shifted left by 2 bits to 65cabdff1aSopenharmony_ci * transform them from 6-bit values to 8-bit values 66cabdff1aSopenharmony_ci * - scan through all 768 palette bytes 67cabdff1aSopenharmony_ci * - if any bytes exceed 63, do not shift the bytes at all before 68cabdff1aSopenharmony_ci * transmitting them to the video decoder 69cabdff1aSopenharmony_ci */ 70cabdff1aSopenharmony_ci 71cabdff1aSopenharmony_ci#include "libavutil/channel_layout.h" 72cabdff1aSopenharmony_ci#include "libavutil/imgutils.h" 73cabdff1aSopenharmony_ci#include "libavutil/intreadwrite.h" 74cabdff1aSopenharmony_ci#include "avformat.h" 75cabdff1aSopenharmony_ci#include "demux.h" 76cabdff1aSopenharmony_ci#include "internal.h" 77cabdff1aSopenharmony_ci 78cabdff1aSopenharmony_ci#define HUFFMAN_TABLE_SIZE (64 * 1024) 79cabdff1aSopenharmony_ci#define IDCIN_FPS 14 80cabdff1aSopenharmony_ci 81cabdff1aSopenharmony_citypedef struct IdcinDemuxContext { 82cabdff1aSopenharmony_ci int video_stream_index; 83cabdff1aSopenharmony_ci int audio_stream_index; 84cabdff1aSopenharmony_ci int audio_chunk_size1; 85cabdff1aSopenharmony_ci int audio_chunk_size2; 86cabdff1aSopenharmony_ci int block_align; 87cabdff1aSopenharmony_ci 88cabdff1aSopenharmony_ci /* demux state variables */ 89cabdff1aSopenharmony_ci int current_audio_chunk; 90cabdff1aSopenharmony_ci int next_chunk_is_video; 91cabdff1aSopenharmony_ci int audio_present; 92cabdff1aSopenharmony_ci int64_t first_pkt_pos; 93cabdff1aSopenharmony_ci} IdcinDemuxContext; 94cabdff1aSopenharmony_ci 95cabdff1aSopenharmony_cistatic int idcin_probe(const AVProbeData *p) 96cabdff1aSopenharmony_ci{ 97cabdff1aSopenharmony_ci unsigned int number, sample_rate; 98cabdff1aSopenharmony_ci unsigned int w, h; 99cabdff1aSopenharmony_ci int i; 100cabdff1aSopenharmony_ci 101cabdff1aSopenharmony_ci /* 102cabdff1aSopenharmony_ci * This is what you could call a "probabilistic" file check: id CIN 103cabdff1aSopenharmony_ci * files don't have a definite file signature. In lieu of such a marker, 104cabdff1aSopenharmony_ci * perform sanity checks on the 5 32-bit header fields: 105cabdff1aSopenharmony_ci * width, height: greater than 0, less than or equal to 1024 106cabdff1aSopenharmony_ci * audio sample rate: greater than or equal to 8000, less than or 107cabdff1aSopenharmony_ci * equal to 48000, or 0 for no audio 108cabdff1aSopenharmony_ci * audio sample width (bytes/sample): 0 for no audio, or 1 or 2 109cabdff1aSopenharmony_ci * audio channels: 0 for no audio, or 1 or 2 110cabdff1aSopenharmony_ci */ 111cabdff1aSopenharmony_ci 112cabdff1aSopenharmony_ci /* check we have enough data to do all checks, otherwise the 113cabdff1aSopenharmony_ci 0-padding may cause a wrong recognition */ 114cabdff1aSopenharmony_ci if (p->buf_size < 20 + HUFFMAN_TABLE_SIZE + 12) 115cabdff1aSopenharmony_ci return 0; 116cabdff1aSopenharmony_ci 117cabdff1aSopenharmony_ci /* check the video width */ 118cabdff1aSopenharmony_ci w = AV_RL32(&p->buf[0]); 119cabdff1aSopenharmony_ci if ((w == 0) || (w > 1024)) 120cabdff1aSopenharmony_ci return 0; 121cabdff1aSopenharmony_ci 122cabdff1aSopenharmony_ci /* check the video height */ 123cabdff1aSopenharmony_ci h = AV_RL32(&p->buf[4]); 124cabdff1aSopenharmony_ci if ((h == 0) || (h > 1024)) 125cabdff1aSopenharmony_ci return 0; 126cabdff1aSopenharmony_ci 127cabdff1aSopenharmony_ci /* check the audio sample rate */ 128cabdff1aSopenharmony_ci sample_rate = AV_RL32(&p->buf[8]); 129cabdff1aSopenharmony_ci if (sample_rate && (sample_rate < 8000 || sample_rate > 48000)) 130cabdff1aSopenharmony_ci return 0; 131cabdff1aSopenharmony_ci 132cabdff1aSopenharmony_ci /* check the audio bytes/sample */ 133cabdff1aSopenharmony_ci number = AV_RL32(&p->buf[12]); 134cabdff1aSopenharmony_ci if (number > 2 || sample_rate && !number) 135cabdff1aSopenharmony_ci return 0; 136cabdff1aSopenharmony_ci 137cabdff1aSopenharmony_ci /* check the audio channels */ 138cabdff1aSopenharmony_ci number = AV_RL32(&p->buf[16]); 139cabdff1aSopenharmony_ci if (number > 2 || sample_rate && !number) 140cabdff1aSopenharmony_ci return 0; 141cabdff1aSopenharmony_ci 142cabdff1aSopenharmony_ci i = 20 + HUFFMAN_TABLE_SIZE; 143cabdff1aSopenharmony_ci if (AV_RL32(&p->buf[i]) == 1) 144cabdff1aSopenharmony_ci i += 768; 145cabdff1aSopenharmony_ci 146cabdff1aSopenharmony_ci if (i+12 > p->buf_size || AV_RL32(&p->buf[i+8]) != w*h) 147cabdff1aSopenharmony_ci return 1; 148cabdff1aSopenharmony_ci 149cabdff1aSopenharmony_ci /* return half certainty since this check is a bit sketchy */ 150cabdff1aSopenharmony_ci return AVPROBE_SCORE_EXTENSION; 151cabdff1aSopenharmony_ci} 152cabdff1aSopenharmony_ci 153cabdff1aSopenharmony_cistatic int idcin_read_header(AVFormatContext *s) 154cabdff1aSopenharmony_ci{ 155cabdff1aSopenharmony_ci AVIOContext *pb = s->pb; 156cabdff1aSopenharmony_ci IdcinDemuxContext *idcin = s->priv_data; 157cabdff1aSopenharmony_ci AVStream *st; 158cabdff1aSopenharmony_ci unsigned int width, height; 159cabdff1aSopenharmony_ci unsigned int sample_rate, bytes_per_sample, channels; 160cabdff1aSopenharmony_ci int ret; 161cabdff1aSopenharmony_ci 162cabdff1aSopenharmony_ci /* get the 5 header parameters */ 163cabdff1aSopenharmony_ci width = avio_rl32(pb); 164cabdff1aSopenharmony_ci height = avio_rl32(pb); 165cabdff1aSopenharmony_ci sample_rate = avio_rl32(pb); 166cabdff1aSopenharmony_ci bytes_per_sample = avio_rl32(pb); 167cabdff1aSopenharmony_ci channels = avio_rl32(pb); 168cabdff1aSopenharmony_ci 169cabdff1aSopenharmony_ci if (s->pb->eof_reached) { 170cabdff1aSopenharmony_ci av_log(s, AV_LOG_ERROR, "incomplete header\n"); 171cabdff1aSopenharmony_ci return s->pb->error ? s->pb->error : AVERROR_EOF; 172cabdff1aSopenharmony_ci } 173cabdff1aSopenharmony_ci 174cabdff1aSopenharmony_ci if (av_image_check_size(width, height, 0, s) < 0) 175cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 176cabdff1aSopenharmony_ci if (sample_rate > 0) { 177cabdff1aSopenharmony_ci if (sample_rate < 14 || sample_rate > INT_MAX) { 178cabdff1aSopenharmony_ci av_log(s, AV_LOG_ERROR, "invalid sample rate: %u\n", sample_rate); 179cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 180cabdff1aSopenharmony_ci } 181cabdff1aSopenharmony_ci if (bytes_per_sample < 1 || bytes_per_sample > 2) { 182cabdff1aSopenharmony_ci av_log(s, AV_LOG_ERROR, "invalid bytes per sample: %u\n", 183cabdff1aSopenharmony_ci bytes_per_sample); 184cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 185cabdff1aSopenharmony_ci } 186cabdff1aSopenharmony_ci if (channels < 1 || channels > 2) { 187cabdff1aSopenharmony_ci av_log(s, AV_LOG_ERROR, "invalid channels: %u\n", channels); 188cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 189cabdff1aSopenharmony_ci } 190cabdff1aSopenharmony_ci idcin->audio_present = 1; 191cabdff1aSopenharmony_ci } else { 192cabdff1aSopenharmony_ci /* if sample rate is 0, assume no audio */ 193cabdff1aSopenharmony_ci idcin->audio_present = 0; 194cabdff1aSopenharmony_ci } 195cabdff1aSopenharmony_ci 196cabdff1aSopenharmony_ci st = avformat_new_stream(s, NULL); 197cabdff1aSopenharmony_ci if (!st) 198cabdff1aSopenharmony_ci return AVERROR(ENOMEM); 199cabdff1aSopenharmony_ci avpriv_set_pts_info(st, 33, 1, IDCIN_FPS); 200cabdff1aSopenharmony_ci st->start_time = 0; 201cabdff1aSopenharmony_ci idcin->video_stream_index = st->index; 202cabdff1aSopenharmony_ci st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO; 203cabdff1aSopenharmony_ci st->codecpar->codec_id = AV_CODEC_ID_IDCIN; 204cabdff1aSopenharmony_ci st->codecpar->codec_tag = 0; /* no fourcc */ 205cabdff1aSopenharmony_ci st->codecpar->width = width; 206cabdff1aSopenharmony_ci st->codecpar->height = height; 207cabdff1aSopenharmony_ci 208cabdff1aSopenharmony_ci /* load up the Huffman tables into extradata */ 209cabdff1aSopenharmony_ci if ((ret = ff_get_extradata(s, st->codecpar, pb, HUFFMAN_TABLE_SIZE)) < 0) 210cabdff1aSopenharmony_ci return ret; 211cabdff1aSopenharmony_ci 212cabdff1aSopenharmony_ci if (idcin->audio_present) { 213cabdff1aSopenharmony_ci idcin->audio_present = 1; 214cabdff1aSopenharmony_ci st = avformat_new_stream(s, NULL); 215cabdff1aSopenharmony_ci if (!st) 216cabdff1aSopenharmony_ci return AVERROR(ENOMEM); 217cabdff1aSopenharmony_ci avpriv_set_pts_info(st, 63, 1, sample_rate); 218cabdff1aSopenharmony_ci st->start_time = 0; 219cabdff1aSopenharmony_ci idcin->audio_stream_index = st->index; 220cabdff1aSopenharmony_ci st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO; 221cabdff1aSopenharmony_ci st->codecpar->codec_tag = 1; 222cabdff1aSopenharmony_ci av_channel_layout_default(&st->codecpar->ch_layout, channels); 223cabdff1aSopenharmony_ci st->codecpar->sample_rate = sample_rate; 224cabdff1aSopenharmony_ci st->codecpar->bits_per_coded_sample = bytes_per_sample * 8; 225cabdff1aSopenharmony_ci st->codecpar->bit_rate = sample_rate * bytes_per_sample * 8 * channels; 226cabdff1aSopenharmony_ci st->codecpar->block_align = idcin->block_align = bytes_per_sample * channels; 227cabdff1aSopenharmony_ci if (bytes_per_sample == 1) 228cabdff1aSopenharmony_ci st->codecpar->codec_id = AV_CODEC_ID_PCM_U8; 229cabdff1aSopenharmony_ci else 230cabdff1aSopenharmony_ci st->codecpar->codec_id = AV_CODEC_ID_PCM_S16LE; 231cabdff1aSopenharmony_ci 232cabdff1aSopenharmony_ci if (sample_rate % 14 != 0) { 233cabdff1aSopenharmony_ci idcin->audio_chunk_size1 = (sample_rate / 14) * 234cabdff1aSopenharmony_ci bytes_per_sample * channels; 235cabdff1aSopenharmony_ci idcin->audio_chunk_size2 = (sample_rate / 14 + 1) * 236cabdff1aSopenharmony_ci bytes_per_sample * channels; 237cabdff1aSopenharmony_ci } else { 238cabdff1aSopenharmony_ci idcin->audio_chunk_size1 = idcin->audio_chunk_size2 = 239cabdff1aSopenharmony_ci (sample_rate / 14) * bytes_per_sample * channels; 240cabdff1aSopenharmony_ci } 241cabdff1aSopenharmony_ci idcin->current_audio_chunk = 0; 242cabdff1aSopenharmony_ci } 243cabdff1aSopenharmony_ci 244cabdff1aSopenharmony_ci idcin->next_chunk_is_video = 1; 245cabdff1aSopenharmony_ci idcin->first_pkt_pos = avio_tell(s->pb); 246cabdff1aSopenharmony_ci 247cabdff1aSopenharmony_ci return 0; 248cabdff1aSopenharmony_ci} 249cabdff1aSopenharmony_ci 250cabdff1aSopenharmony_cistatic int idcin_read_packet(AVFormatContext *s, 251cabdff1aSopenharmony_ci AVPacket *pkt) 252cabdff1aSopenharmony_ci{ 253cabdff1aSopenharmony_ci int ret; 254cabdff1aSopenharmony_ci unsigned int command; 255cabdff1aSopenharmony_ci unsigned int chunk_size; 256cabdff1aSopenharmony_ci IdcinDemuxContext *idcin = s->priv_data; 257cabdff1aSopenharmony_ci AVIOContext *pb = s->pb; 258cabdff1aSopenharmony_ci int i; 259cabdff1aSopenharmony_ci int palette_scale; 260cabdff1aSopenharmony_ci unsigned char r, g, b; 261cabdff1aSopenharmony_ci unsigned char palette_buffer[768]; 262cabdff1aSopenharmony_ci uint32_t palette[256]; 263cabdff1aSopenharmony_ci 264cabdff1aSopenharmony_ci if (avio_feof(s->pb)) 265cabdff1aSopenharmony_ci return s->pb->error ? s->pb->error : AVERROR_EOF; 266cabdff1aSopenharmony_ci 267cabdff1aSopenharmony_ci if (idcin->next_chunk_is_video) { 268cabdff1aSopenharmony_ci command = avio_rl32(pb); 269cabdff1aSopenharmony_ci if (command == 2) { 270cabdff1aSopenharmony_ci return AVERROR(EIO); 271cabdff1aSopenharmony_ci } else if (command == 1) { 272cabdff1aSopenharmony_ci /* trigger a palette change */ 273cabdff1aSopenharmony_ci ret = avio_read(pb, palette_buffer, 768); 274cabdff1aSopenharmony_ci if (ret < 0) { 275cabdff1aSopenharmony_ci return ret; 276cabdff1aSopenharmony_ci } else if (ret != 768) { 277cabdff1aSopenharmony_ci av_log(s, AV_LOG_ERROR, "incomplete packet\n"); 278cabdff1aSopenharmony_ci return AVERROR(EIO); 279cabdff1aSopenharmony_ci } 280cabdff1aSopenharmony_ci /* scale the palette as necessary */ 281cabdff1aSopenharmony_ci palette_scale = 2; 282cabdff1aSopenharmony_ci for (i = 0; i < 768; i++) 283cabdff1aSopenharmony_ci if (palette_buffer[i] > 63) { 284cabdff1aSopenharmony_ci palette_scale = 0; 285cabdff1aSopenharmony_ci break; 286cabdff1aSopenharmony_ci } 287cabdff1aSopenharmony_ci 288cabdff1aSopenharmony_ci for (i = 0; i < 256; i++) { 289cabdff1aSopenharmony_ci r = palette_buffer[i * 3 ] << palette_scale; 290cabdff1aSopenharmony_ci g = palette_buffer[i * 3 + 1] << palette_scale; 291cabdff1aSopenharmony_ci b = palette_buffer[i * 3 + 2] << palette_scale; 292cabdff1aSopenharmony_ci palette[i] = (0xFFU << 24) | (r << 16) | (g << 8) | (b); 293cabdff1aSopenharmony_ci if (palette_scale == 2) 294cabdff1aSopenharmony_ci palette[i] |= palette[i] >> 6 & 0x30303; 295cabdff1aSopenharmony_ci } 296cabdff1aSopenharmony_ci } 297cabdff1aSopenharmony_ci 298cabdff1aSopenharmony_ci if (s->pb->eof_reached) { 299cabdff1aSopenharmony_ci av_log(s, AV_LOG_ERROR, "incomplete packet\n"); 300cabdff1aSopenharmony_ci return s->pb->error ? s->pb->error : AVERROR_EOF; 301cabdff1aSopenharmony_ci } 302cabdff1aSopenharmony_ci chunk_size = avio_rl32(pb); 303cabdff1aSopenharmony_ci if (chunk_size < 4 || chunk_size > INT_MAX - 4) { 304cabdff1aSopenharmony_ci av_log(s, AV_LOG_ERROR, "invalid chunk size: %u\n", chunk_size); 305cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 306cabdff1aSopenharmony_ci } 307cabdff1aSopenharmony_ci /* skip the number of decoded bytes (always equal to width * height) */ 308cabdff1aSopenharmony_ci avio_skip(pb, 4); 309cabdff1aSopenharmony_ci chunk_size -= 4; 310cabdff1aSopenharmony_ci ret= av_get_packet(pb, pkt, chunk_size); 311cabdff1aSopenharmony_ci if (ret < 0) 312cabdff1aSopenharmony_ci return ret; 313cabdff1aSopenharmony_ci else if (ret != chunk_size) { 314cabdff1aSopenharmony_ci av_log(s, AV_LOG_ERROR, "incomplete packet\n"); 315cabdff1aSopenharmony_ci return AVERROR(EIO); 316cabdff1aSopenharmony_ci } 317cabdff1aSopenharmony_ci if (command == 1) { 318cabdff1aSopenharmony_ci uint8_t *pal; 319cabdff1aSopenharmony_ci 320cabdff1aSopenharmony_ci pal = av_packet_new_side_data(pkt, AV_PKT_DATA_PALETTE, 321cabdff1aSopenharmony_ci AVPALETTE_SIZE); 322cabdff1aSopenharmony_ci if (!pal) { 323cabdff1aSopenharmony_ci return AVERROR(ENOMEM); 324cabdff1aSopenharmony_ci } 325cabdff1aSopenharmony_ci memcpy(pal, palette, AVPALETTE_SIZE); 326cabdff1aSopenharmony_ci pkt->flags |= AV_PKT_FLAG_KEY; 327cabdff1aSopenharmony_ci } 328cabdff1aSopenharmony_ci pkt->stream_index = idcin->video_stream_index; 329cabdff1aSopenharmony_ci pkt->duration = 1; 330cabdff1aSopenharmony_ci } else { 331cabdff1aSopenharmony_ci /* send out the audio chunk */ 332cabdff1aSopenharmony_ci if (idcin->current_audio_chunk) 333cabdff1aSopenharmony_ci chunk_size = idcin->audio_chunk_size2; 334cabdff1aSopenharmony_ci else 335cabdff1aSopenharmony_ci chunk_size = idcin->audio_chunk_size1; 336cabdff1aSopenharmony_ci ret= av_get_packet(pb, pkt, chunk_size); 337cabdff1aSopenharmony_ci if (ret < 0) 338cabdff1aSopenharmony_ci return ret; 339cabdff1aSopenharmony_ci pkt->stream_index = idcin->audio_stream_index; 340cabdff1aSopenharmony_ci pkt->duration = chunk_size / idcin->block_align; 341cabdff1aSopenharmony_ci 342cabdff1aSopenharmony_ci idcin->current_audio_chunk ^= 1; 343cabdff1aSopenharmony_ci } 344cabdff1aSopenharmony_ci 345cabdff1aSopenharmony_ci if (idcin->audio_present) 346cabdff1aSopenharmony_ci idcin->next_chunk_is_video ^= 1; 347cabdff1aSopenharmony_ci 348cabdff1aSopenharmony_ci return 0; 349cabdff1aSopenharmony_ci} 350cabdff1aSopenharmony_ci 351cabdff1aSopenharmony_cistatic int idcin_read_seek(AVFormatContext *s, int stream_index, 352cabdff1aSopenharmony_ci int64_t timestamp, int flags) 353cabdff1aSopenharmony_ci{ 354cabdff1aSopenharmony_ci IdcinDemuxContext *idcin = s->priv_data; 355cabdff1aSopenharmony_ci 356cabdff1aSopenharmony_ci if (idcin->first_pkt_pos > 0) { 357cabdff1aSopenharmony_ci int64_t ret = avio_seek(s->pb, idcin->first_pkt_pos, SEEK_SET); 358cabdff1aSopenharmony_ci if (ret < 0) 359cabdff1aSopenharmony_ci return ret; 360cabdff1aSopenharmony_ci avpriv_update_cur_dts(s, s->streams[idcin->video_stream_index], 0); 361cabdff1aSopenharmony_ci idcin->next_chunk_is_video = 1; 362cabdff1aSopenharmony_ci idcin->current_audio_chunk = 0; 363cabdff1aSopenharmony_ci return 0; 364cabdff1aSopenharmony_ci } 365cabdff1aSopenharmony_ci return -1; 366cabdff1aSopenharmony_ci} 367cabdff1aSopenharmony_ci 368cabdff1aSopenharmony_ciconst AVInputFormat ff_idcin_demuxer = { 369cabdff1aSopenharmony_ci .name = "idcin", 370cabdff1aSopenharmony_ci .long_name = NULL_IF_CONFIG_SMALL("id Cinematic"), 371cabdff1aSopenharmony_ci .priv_data_size = sizeof(IdcinDemuxContext), 372cabdff1aSopenharmony_ci .read_probe = idcin_probe, 373cabdff1aSopenharmony_ci .read_header = idcin_read_header, 374cabdff1aSopenharmony_ci .read_packet = idcin_read_packet, 375cabdff1aSopenharmony_ci .read_seek = idcin_read_seek, 376cabdff1aSopenharmony_ci .flags = AVFMT_NO_BYTE_SEEK, 377cabdff1aSopenharmony_ci}; 378