1cabdff1aSopenharmony_ci/* 2cabdff1aSopenharmony_ci * Bink demuxer 3cabdff1aSopenharmony_ci * Copyright (c) 2008-2010 Peter Ross (pross@xvid.org) 4cabdff1aSopenharmony_ci * Copyright (c) 2009 Daniel Verkamp (daniel@drv.nu) 5cabdff1aSopenharmony_ci * 6cabdff1aSopenharmony_ci * This file is part of FFmpeg. 7cabdff1aSopenharmony_ci * 8cabdff1aSopenharmony_ci * FFmpeg is free software; you can redistribute it and/or 9cabdff1aSopenharmony_ci * modify it under the terms of the GNU Lesser General Public 10cabdff1aSopenharmony_ci * License as published by the Free Software Foundation; either 11cabdff1aSopenharmony_ci * version 2.1 of the License, or (at your option) any later version. 12cabdff1aSopenharmony_ci * 13cabdff1aSopenharmony_ci * FFmpeg is distributed in the hope that it will be useful, 14cabdff1aSopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of 15cabdff1aSopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16cabdff1aSopenharmony_ci * Lesser General Public License for more details. 17cabdff1aSopenharmony_ci * 18cabdff1aSopenharmony_ci * You should have received a copy of the GNU Lesser General Public 19cabdff1aSopenharmony_ci * License along with FFmpeg; if not, write to the Free Software 20cabdff1aSopenharmony_ci * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 21cabdff1aSopenharmony_ci */ 22cabdff1aSopenharmony_ci 23cabdff1aSopenharmony_ci/** 24cabdff1aSopenharmony_ci * @file 25cabdff1aSopenharmony_ci * Bink demuxer 26cabdff1aSopenharmony_ci * 27cabdff1aSopenharmony_ci * Technical details here: 28cabdff1aSopenharmony_ci * http://wiki.multimedia.cx/index.php?title=Bink_Container 29cabdff1aSopenharmony_ci */ 30cabdff1aSopenharmony_ci 31cabdff1aSopenharmony_ci#include <inttypes.h> 32cabdff1aSopenharmony_ci 33cabdff1aSopenharmony_ci#include "libavutil/channel_layout.h" 34cabdff1aSopenharmony_ci#include "libavutil/intreadwrite.h" 35cabdff1aSopenharmony_ci#include "avformat.h" 36cabdff1aSopenharmony_ci#include "demux.h" 37cabdff1aSopenharmony_ci#include "internal.h" 38cabdff1aSopenharmony_ci 39cabdff1aSopenharmony_cienum BinkAudFlags { 40cabdff1aSopenharmony_ci BINK_AUD_16BITS = 0x4000, ///< prefer 16-bit output 41cabdff1aSopenharmony_ci BINK_AUD_STEREO = 0x2000, 42cabdff1aSopenharmony_ci BINK_AUD_USEDCT = 0x1000, 43cabdff1aSopenharmony_ci}; 44cabdff1aSopenharmony_ci 45cabdff1aSopenharmony_ci#define BINK_EXTRADATA_SIZE 1 46cabdff1aSopenharmony_ci#define BINK_MAX_AUDIO_TRACKS 256 47cabdff1aSopenharmony_ci#define BINK_MAX_WIDTH 7680 48cabdff1aSopenharmony_ci#define BINK_MAX_HEIGHT 4800 49cabdff1aSopenharmony_ci#define SMUSH_BLOCK_SIZE 512 50cabdff1aSopenharmony_ci 51cabdff1aSopenharmony_citypedef struct BinkDemuxContext { 52cabdff1aSopenharmony_ci uint32_t file_size; 53cabdff1aSopenharmony_ci 54cabdff1aSopenharmony_ci uint32_t num_audio_tracks; 55cabdff1aSopenharmony_ci int current_track; ///< audio track to return in next packet 56cabdff1aSopenharmony_ci int64_t video_pts; 57cabdff1aSopenharmony_ci int64_t audio_pts[BINK_MAX_AUDIO_TRACKS]; 58cabdff1aSopenharmony_ci 59cabdff1aSopenharmony_ci uint32_t remain_packet_size; 60cabdff1aSopenharmony_ci int flags; 61cabdff1aSopenharmony_ci int smush_size; 62cabdff1aSopenharmony_ci} BinkDemuxContext; 63cabdff1aSopenharmony_ci 64cabdff1aSopenharmony_cistatic int probe(const AVProbeData *p) 65cabdff1aSopenharmony_ci{ 66cabdff1aSopenharmony_ci const uint8_t *b = p->buf; 67cabdff1aSopenharmony_ci int smush = AV_RN32(p->buf) == AV_RN32("SMUS"); 68cabdff1aSopenharmony_ci 69cabdff1aSopenharmony_ci do { 70cabdff1aSopenharmony_ci if (((b[0] == 'B' && b[1] == 'I' && b[2] == 'K' && /* Bink 1 */ 71cabdff1aSopenharmony_ci (b[3] == 'b' || b[3] == 'f' || b[3] == 'g' || b[3] == 'h' || b[3] == 'i' || 72cabdff1aSopenharmony_ci b[3] == 'k')) || 73cabdff1aSopenharmony_ci (b[0] == 'K' && b[1] == 'B' && b[2] == '2' && /* Bink 2 */ 74cabdff1aSopenharmony_ci (b[3] == 'a' || b[3] == 'd' || b[3] == 'f' || b[3] == 'g' || b[3] == 'h' || 75cabdff1aSopenharmony_ci b[3] == 'i' || b[3] == 'j' || b[3] == 'k'))) && 76cabdff1aSopenharmony_ci AV_RL32(b+8) > 0 && // num_frames 77cabdff1aSopenharmony_ci AV_RL32(b+20) > 0 && AV_RL32(b+20) <= BINK_MAX_WIDTH && 78cabdff1aSopenharmony_ci AV_RL32(b+24) > 0 && AV_RL32(b+24) <= BINK_MAX_HEIGHT && 79cabdff1aSopenharmony_ci AV_RL32(b+28) > 0 && AV_RL32(b+32) > 0) // fps num,den 80cabdff1aSopenharmony_ci return AVPROBE_SCORE_MAX; 81cabdff1aSopenharmony_ci b += SMUSH_BLOCK_SIZE; 82cabdff1aSopenharmony_ci } while (smush && b < p->buf + p->buf_size - 32); 83cabdff1aSopenharmony_ci return 0; 84cabdff1aSopenharmony_ci} 85cabdff1aSopenharmony_ci 86cabdff1aSopenharmony_cistatic int read_header(AVFormatContext *s) 87cabdff1aSopenharmony_ci{ 88cabdff1aSopenharmony_ci BinkDemuxContext *bink = s->priv_data; 89cabdff1aSopenharmony_ci AVIOContext *pb = s->pb; 90cabdff1aSopenharmony_ci uint32_t fps_num, fps_den; 91cabdff1aSopenharmony_ci AVStream *const vst = avformat_new_stream(s, NULL); 92cabdff1aSopenharmony_ci FFStream *const vsti = ffstream(vst); 93cabdff1aSopenharmony_ci unsigned int i; 94cabdff1aSopenharmony_ci uint32_t pos, next_pos; 95cabdff1aSopenharmony_ci uint16_t flags; 96cabdff1aSopenharmony_ci int next_keyframe = 1; 97cabdff1aSopenharmony_ci int keyframe; 98cabdff1aSopenharmony_ci int ret; 99cabdff1aSopenharmony_ci uint32_t signature; 100cabdff1aSopenharmony_ci uint8_t revision; 101cabdff1aSopenharmony_ci 102cabdff1aSopenharmony_ci if (!vst) 103cabdff1aSopenharmony_ci return AVERROR(ENOMEM); 104cabdff1aSopenharmony_ci 105cabdff1aSopenharmony_ci vst->codecpar->codec_tag = avio_rl32(pb); 106cabdff1aSopenharmony_ci if (vst->codecpar->codec_tag == AV_RL32("SMUS")) { 107cabdff1aSopenharmony_ci do { 108cabdff1aSopenharmony_ci bink->smush_size += SMUSH_BLOCK_SIZE; 109cabdff1aSopenharmony_ci avio_skip(pb, SMUSH_BLOCK_SIZE - 4); 110cabdff1aSopenharmony_ci vst->codecpar->codec_tag = avio_rl32(pb); 111cabdff1aSopenharmony_ci } while (!avio_feof(pb) && (vst->codecpar->codec_tag & 0xFFFFFF) != AV_RL32("BIK")); 112cabdff1aSopenharmony_ci if (avio_feof(pb)) { 113cabdff1aSopenharmony_ci av_log(s, AV_LOG_ERROR, "invalid SMUSH header: BIK not found\n"); 114cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 115cabdff1aSopenharmony_ci } 116cabdff1aSopenharmony_ci } 117cabdff1aSopenharmony_ci 118cabdff1aSopenharmony_ci bink->file_size = avio_rl32(pb) + 8; 119cabdff1aSopenharmony_ci vst->duration = avio_rl32(pb); 120cabdff1aSopenharmony_ci 121cabdff1aSopenharmony_ci if (vst->duration > 1000000) { 122cabdff1aSopenharmony_ci av_log(s, AV_LOG_ERROR, "invalid header: more than 1000000 frames\n"); 123cabdff1aSopenharmony_ci return AVERROR(EIO); 124cabdff1aSopenharmony_ci } 125cabdff1aSopenharmony_ci 126cabdff1aSopenharmony_ci if (avio_rl32(pb) > bink->file_size) { 127cabdff1aSopenharmony_ci av_log(s, AV_LOG_ERROR, 128cabdff1aSopenharmony_ci "invalid header: largest frame size greater than file size\n"); 129cabdff1aSopenharmony_ci return AVERROR(EIO); 130cabdff1aSopenharmony_ci } 131cabdff1aSopenharmony_ci 132cabdff1aSopenharmony_ci avio_skip(pb, 4); 133cabdff1aSopenharmony_ci 134cabdff1aSopenharmony_ci vst->codecpar->width = avio_rl32(pb); 135cabdff1aSopenharmony_ci vst->codecpar->height = avio_rl32(pb); 136cabdff1aSopenharmony_ci 137cabdff1aSopenharmony_ci fps_num = avio_rl32(pb); 138cabdff1aSopenharmony_ci fps_den = avio_rl32(pb); 139cabdff1aSopenharmony_ci if (fps_num == 0 || fps_den == 0) { 140cabdff1aSopenharmony_ci av_log(s, AV_LOG_ERROR, 141cabdff1aSopenharmony_ci "invalid header: invalid fps (%"PRIu32"/%"PRIu32")\n", 142cabdff1aSopenharmony_ci fps_num, fps_den); 143cabdff1aSopenharmony_ci return AVERROR(EIO); 144cabdff1aSopenharmony_ci } 145cabdff1aSopenharmony_ci avpriv_set_pts_info(vst, 64, fps_den, fps_num); 146cabdff1aSopenharmony_ci vst->avg_frame_rate = av_inv_q(vst->time_base); 147cabdff1aSopenharmony_ci 148cabdff1aSopenharmony_ci vst->codecpar->codec_type = AVMEDIA_TYPE_VIDEO; 149cabdff1aSopenharmony_ci vst->codecpar->codec_id = AV_CODEC_ID_BINKVIDEO; 150cabdff1aSopenharmony_ci 151cabdff1aSopenharmony_ci if ((vst->codecpar->codec_tag & 0xFFFFFF) == MKTAG('K', 'B', '2', 0)) { 152cabdff1aSopenharmony_ci av_log(s, AV_LOG_WARNING, "Bink 2 video is not implemented\n"); 153cabdff1aSopenharmony_ci vst->codecpar->codec_id = AV_CODEC_ID_NONE; 154cabdff1aSopenharmony_ci } 155cabdff1aSopenharmony_ci 156cabdff1aSopenharmony_ci if ((ret = ff_get_extradata(s, vst->codecpar, pb, 4)) < 0) 157cabdff1aSopenharmony_ci return ret; 158cabdff1aSopenharmony_ci 159cabdff1aSopenharmony_ci bink->num_audio_tracks = avio_rl32(pb); 160cabdff1aSopenharmony_ci 161cabdff1aSopenharmony_ci if (bink->num_audio_tracks > BINK_MAX_AUDIO_TRACKS) { 162cabdff1aSopenharmony_ci av_log(s, AV_LOG_ERROR, 163cabdff1aSopenharmony_ci "invalid header: more than "AV_STRINGIFY(BINK_MAX_AUDIO_TRACKS)" audio tracks (%"PRIu32")\n", 164cabdff1aSopenharmony_ci bink->num_audio_tracks); 165cabdff1aSopenharmony_ci return AVERROR(EIO); 166cabdff1aSopenharmony_ci } 167cabdff1aSopenharmony_ci 168cabdff1aSopenharmony_ci signature = (vst->codecpar->codec_tag & 0xFFFFFF); 169cabdff1aSopenharmony_ci revision = ((vst->codecpar->codec_tag >> 24) % 0xFF); 170cabdff1aSopenharmony_ci 171cabdff1aSopenharmony_ci if ((signature == AV_RL32("BIK") && (revision == 'k')) || 172cabdff1aSopenharmony_ci (signature == AV_RL32("KB2") && (revision == 'i' || revision == 'j' || revision == 'k'))) 173cabdff1aSopenharmony_ci avio_skip(pb, 4); /* unknown new field */ 174cabdff1aSopenharmony_ci 175cabdff1aSopenharmony_ci if (bink->num_audio_tracks) { 176cabdff1aSopenharmony_ci avio_skip(pb, 4 * bink->num_audio_tracks); /* max decoded size */ 177cabdff1aSopenharmony_ci 178cabdff1aSopenharmony_ci for (i = 0; i < bink->num_audio_tracks; i++) { 179cabdff1aSopenharmony_ci AVStream *const ast = avformat_new_stream(s, NULL); 180cabdff1aSopenharmony_ci if (!ast) 181cabdff1aSopenharmony_ci return AVERROR(ENOMEM); 182cabdff1aSopenharmony_ci ast->codecpar->codec_type = AVMEDIA_TYPE_AUDIO; 183cabdff1aSopenharmony_ci ast->codecpar->codec_tag = 0; 184cabdff1aSopenharmony_ci ast->codecpar->sample_rate = avio_rl16(pb); 185cabdff1aSopenharmony_ci avpriv_set_pts_info(ast, 64, 1, ast->codecpar->sample_rate); 186cabdff1aSopenharmony_ci flags = avio_rl16(pb); 187cabdff1aSopenharmony_ci ast->codecpar->codec_id = flags & BINK_AUD_USEDCT ? 188cabdff1aSopenharmony_ci AV_CODEC_ID_BINKAUDIO_DCT : AV_CODEC_ID_BINKAUDIO_RDFT; 189cabdff1aSopenharmony_ci if (flags & BINK_AUD_STEREO) { 190cabdff1aSopenharmony_ci ast->codecpar->ch_layout = (AVChannelLayout)AV_CHANNEL_LAYOUT_STEREO; 191cabdff1aSopenharmony_ci } else { 192cabdff1aSopenharmony_ci ast->codecpar->ch_layout = (AVChannelLayout)AV_CHANNEL_LAYOUT_MONO; 193cabdff1aSopenharmony_ci } 194cabdff1aSopenharmony_ci if ((ret = ff_alloc_extradata(ast->codecpar, 4)) < 0) 195cabdff1aSopenharmony_ci return ret; 196cabdff1aSopenharmony_ci AV_WL32(ast->codecpar->extradata, vst->codecpar->codec_tag); 197cabdff1aSopenharmony_ci } 198cabdff1aSopenharmony_ci 199cabdff1aSopenharmony_ci for (i = 0; i < bink->num_audio_tracks; i++) 200cabdff1aSopenharmony_ci s->streams[i + 1]->id = avio_rl32(pb); 201cabdff1aSopenharmony_ci } 202cabdff1aSopenharmony_ci 203cabdff1aSopenharmony_ci /* frame index table */ 204cabdff1aSopenharmony_ci next_pos = avio_rl32(pb); 205cabdff1aSopenharmony_ci for (i = 0; i < vst->duration; i++) { 206cabdff1aSopenharmony_ci pos = next_pos; 207cabdff1aSopenharmony_ci keyframe = next_keyframe; 208cabdff1aSopenharmony_ci if (i == vst->duration - 1) { 209cabdff1aSopenharmony_ci next_pos = bink->file_size; 210cabdff1aSopenharmony_ci next_keyframe = 0; 211cabdff1aSopenharmony_ci } else { 212cabdff1aSopenharmony_ci next_pos = avio_rl32(pb); 213cabdff1aSopenharmony_ci next_keyframe = next_pos & 1; 214cabdff1aSopenharmony_ci } 215cabdff1aSopenharmony_ci pos &= ~1; 216cabdff1aSopenharmony_ci next_pos &= ~1; 217cabdff1aSopenharmony_ci 218cabdff1aSopenharmony_ci if (next_pos <= pos) { 219cabdff1aSopenharmony_ci av_log(s, AV_LOG_ERROR, "invalid frame index table\n"); 220cabdff1aSopenharmony_ci return AVERROR(EIO); 221cabdff1aSopenharmony_ci } 222cabdff1aSopenharmony_ci if ((ret = av_add_index_entry(vst, pos, i, next_pos - pos, 0, 223cabdff1aSopenharmony_ci keyframe ? AVINDEX_KEYFRAME : 0)) < 0) 224cabdff1aSopenharmony_ci return ret; 225cabdff1aSopenharmony_ci } 226cabdff1aSopenharmony_ci 227cabdff1aSopenharmony_ci if (vsti->index_entries) 228cabdff1aSopenharmony_ci avio_seek(pb, vsti->index_entries[0].pos + bink->smush_size, SEEK_SET); 229cabdff1aSopenharmony_ci else 230cabdff1aSopenharmony_ci avio_skip(pb, 4); 231cabdff1aSopenharmony_ci 232cabdff1aSopenharmony_ci bink->current_track = -1; 233cabdff1aSopenharmony_ci return 0; 234cabdff1aSopenharmony_ci} 235cabdff1aSopenharmony_ci 236cabdff1aSopenharmony_cistatic int read_packet(AVFormatContext *s, AVPacket *pkt) 237cabdff1aSopenharmony_ci{ 238cabdff1aSopenharmony_ci BinkDemuxContext *bink = s->priv_data; 239cabdff1aSopenharmony_ci AVIOContext *pb = s->pb; 240cabdff1aSopenharmony_ci int ret; 241cabdff1aSopenharmony_ci 242cabdff1aSopenharmony_ci if (bink->current_track < 0) { 243cabdff1aSopenharmony_ci int index_entry; 244cabdff1aSopenharmony_ci AVStream *st = s->streams[0]; // stream 0 is video stream with index 245cabdff1aSopenharmony_ci FFStream *const sti = ffstream(st); 246cabdff1aSopenharmony_ci 247cabdff1aSopenharmony_ci if (bink->video_pts >= st->duration) 248cabdff1aSopenharmony_ci return AVERROR_EOF; 249cabdff1aSopenharmony_ci 250cabdff1aSopenharmony_ci index_entry = av_index_search_timestamp(st, bink->video_pts, 251cabdff1aSopenharmony_ci AVSEEK_FLAG_ANY); 252cabdff1aSopenharmony_ci if (index_entry < 0) { 253cabdff1aSopenharmony_ci av_log(s, AV_LOG_ERROR, 254cabdff1aSopenharmony_ci "could not find index entry for frame %"PRId64"\n", 255cabdff1aSopenharmony_ci bink->video_pts); 256cabdff1aSopenharmony_ci return AVERROR(EIO); 257cabdff1aSopenharmony_ci } 258cabdff1aSopenharmony_ci 259cabdff1aSopenharmony_ci bink->remain_packet_size = sti->index_entries[index_entry].size; 260cabdff1aSopenharmony_ci bink->flags = sti->index_entries[index_entry].flags; 261cabdff1aSopenharmony_ci bink->current_track = 0; 262cabdff1aSopenharmony_ci } 263cabdff1aSopenharmony_ci 264cabdff1aSopenharmony_ci while (bink->current_track < bink->num_audio_tracks) { 265cabdff1aSopenharmony_ci uint32_t audio_size = avio_rl32(pb); 266cabdff1aSopenharmony_ci if (audio_size > bink->remain_packet_size - 4) { 267cabdff1aSopenharmony_ci av_log(s, AV_LOG_ERROR, 268cabdff1aSopenharmony_ci "frame %"PRId64": audio size in header (%"PRIu32") > size of packet left (%"PRIu32")\n", 269cabdff1aSopenharmony_ci bink->video_pts, audio_size, bink->remain_packet_size); 270cabdff1aSopenharmony_ci return AVERROR(EIO); 271cabdff1aSopenharmony_ci } 272cabdff1aSopenharmony_ci bink->remain_packet_size -= 4 + audio_size; 273cabdff1aSopenharmony_ci bink->current_track++; 274cabdff1aSopenharmony_ci if (audio_size >= 4) { 275cabdff1aSopenharmony_ci /* get one audio packet per track */ 276cabdff1aSopenharmony_ci if ((ret = av_get_packet(pb, pkt, audio_size)) < 0) 277cabdff1aSopenharmony_ci return ret; 278cabdff1aSopenharmony_ci pkt->stream_index = bink->current_track; 279cabdff1aSopenharmony_ci pkt->pts = bink->audio_pts[bink->current_track - 1]; 280cabdff1aSopenharmony_ci 281cabdff1aSopenharmony_ci /* Each audio packet reports the number of decompressed samples 282cabdff1aSopenharmony_ci (in bytes). We use this value to calculate the audio PTS */ 283cabdff1aSopenharmony_ci if (pkt->size >= 4) 284cabdff1aSopenharmony_ci bink->audio_pts[bink->current_track -1] += 285cabdff1aSopenharmony_ci AV_RL32(pkt->data) / (2 * s->streams[bink->current_track]->codecpar->ch_layout.nb_channels); 286cabdff1aSopenharmony_ci return 0; 287cabdff1aSopenharmony_ci } else { 288cabdff1aSopenharmony_ci avio_skip(pb, audio_size); 289cabdff1aSopenharmony_ci } 290cabdff1aSopenharmony_ci } 291cabdff1aSopenharmony_ci 292cabdff1aSopenharmony_ci /* get video packet */ 293cabdff1aSopenharmony_ci if ((ret = av_get_packet(pb, pkt, bink->remain_packet_size)) < 0) 294cabdff1aSopenharmony_ci return ret; 295cabdff1aSopenharmony_ci pkt->stream_index = 0; 296cabdff1aSopenharmony_ci pkt->pts = bink->video_pts++; 297cabdff1aSopenharmony_ci if (bink->flags & AVINDEX_KEYFRAME) 298cabdff1aSopenharmony_ci pkt->flags |= AV_PKT_FLAG_KEY; 299cabdff1aSopenharmony_ci 300cabdff1aSopenharmony_ci /* -1 instructs the next call to read_packet() to read the next frame */ 301cabdff1aSopenharmony_ci bink->current_track = -1; 302cabdff1aSopenharmony_ci 303cabdff1aSopenharmony_ci return 0; 304cabdff1aSopenharmony_ci} 305cabdff1aSopenharmony_ci 306cabdff1aSopenharmony_cistatic int read_seek(AVFormatContext *s, int stream_index, int64_t timestamp, int flags) 307cabdff1aSopenharmony_ci{ 308cabdff1aSopenharmony_ci BinkDemuxContext *bink = s->priv_data; 309cabdff1aSopenharmony_ci AVStream *vst = s->streams[0]; 310cabdff1aSopenharmony_ci FFStream *const vsti = ffstream(vst); 311cabdff1aSopenharmony_ci int64_t ret; 312cabdff1aSopenharmony_ci 313cabdff1aSopenharmony_ci if (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL)) 314cabdff1aSopenharmony_ci return -1; 315cabdff1aSopenharmony_ci 316cabdff1aSopenharmony_ci /* seek to the first frame */ 317cabdff1aSopenharmony_ci ret = avio_seek(s->pb, vsti->index_entries[0].pos + bink->smush_size, SEEK_SET); 318cabdff1aSopenharmony_ci if (ret < 0) 319cabdff1aSopenharmony_ci return ret; 320cabdff1aSopenharmony_ci 321cabdff1aSopenharmony_ci bink->video_pts = 0; 322cabdff1aSopenharmony_ci memset(bink->audio_pts, 0, sizeof(bink->audio_pts)); 323cabdff1aSopenharmony_ci bink->current_track = -1; 324cabdff1aSopenharmony_ci return 0; 325cabdff1aSopenharmony_ci} 326cabdff1aSopenharmony_ci 327cabdff1aSopenharmony_ciconst AVInputFormat ff_bink_demuxer = { 328cabdff1aSopenharmony_ci .name = "bink", 329cabdff1aSopenharmony_ci .long_name = NULL_IF_CONFIG_SMALL("Bink"), 330cabdff1aSopenharmony_ci .priv_data_size = sizeof(BinkDemuxContext), 331cabdff1aSopenharmony_ci .read_probe = probe, 332cabdff1aSopenharmony_ci .read_header = read_header, 333cabdff1aSopenharmony_ci .read_packet = read_packet, 334cabdff1aSopenharmony_ci .read_seek = read_seek, 335cabdff1aSopenharmony_ci .flags = AVFMT_SHOW_IDS, 336cabdff1aSopenharmony_ci}; 337