X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavformat%2Fbink.c;h=32247904854541e1bb10109e93798e3777e28868;hb=c201069fac9a76e6604f9d84d76a172434d62200;hp=3bb73610adfbddfc56f4a195ad3da6abeddb4b2f;hpb=72415b2adb2c25f95ceede49001bb97ed9247dbb;p=ffmpeg diff --git a/libavformat/bink.c b/libavformat/bink.c index 3bb73610adf..32247904854 100644 --- a/libavformat/bink.c +++ b/libavformat/bink.c @@ -3,33 +3,37 @@ * Copyright (c) 2008-2010 Peter Ross (pross@xvid.org) * Copyright (c) 2009 Daniel Verkamp (daniel@drv.nu) * - * This file is part of FFmpeg. + * This file is part of Libav. * - * FFmpeg is free software; you can redistribute it and/or + * Libav is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * - * FFmpeg is distributed in the hope that it will be useful, + * Libav is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software + * License along with Libav; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ /** - * @file libavformat/bink.c + * @file * Bink demuxer * * Technical details here: * http://wiki.multimedia.cx/index.php?title=Bink_Container */ +#include + +#include "libavutil/channel_layout.h" #include "libavutil/intreadwrite.h" #include "avformat.h" +#include "internal.h" enum BinkAudFlags { BINK_AUD_16BITS = 0x4000, ///< prefer 16-bit output @@ -42,7 +46,7 @@ enum BinkAudFlags { #define BINK_MAX_WIDTH 7680 #define BINK_MAX_HEIGHT 4800 -typedef struct { +typedef struct BinkDemuxContext { uint32_t file_size; uint32_t num_audio_tracks; @@ -67,10 +71,10 @@ static int probe(AVProbeData *p) return 0; } -static int read_header(AVFormatContext *s, AVFormatParameters *ap) +static int read_header(AVFormatContext *s) { BinkDemuxContext *bink = s->priv_data; - ByteIOContext *pb = s->pb; + AVIOContext *pb = s->pb; uint32_t fps_num, fps_den; AVStream *vst, *ast; unsigned int i; @@ -78,83 +82,100 @@ static int read_header(AVFormatContext *s, AVFormatParameters *ap) uint16_t flags; int keyframe; - vst = av_new_stream(s, 0); + vst = avformat_new_stream(s, NULL); if (!vst) return AVERROR(ENOMEM); - vst->codec->codec_tag = get_le32(pb); + vst->codec->codec_tag = avio_rl32(pb); - bink->file_size = get_le32(pb) + 8; - vst->duration = get_le32(pb); + bink->file_size = avio_rl32(pb) + 8; + vst->duration = avio_rl32(pb); if (vst->duration > 1000000) { av_log(s, AV_LOG_ERROR, "invalid header: more than 1000000 frames\n"); return AVERROR(EIO); } - if (get_le32(pb) > bink->file_size) { + if (avio_rl32(pb) > bink->file_size) { av_log(s, AV_LOG_ERROR, "invalid header: largest frame size greater than file size\n"); return AVERROR(EIO); } - url_fskip(pb, 4); + avio_skip(pb, 4); - vst->codec->width = get_le32(pb); - vst->codec->height = get_le32(pb); + vst->codec->width = avio_rl32(pb); + vst->codec->height = avio_rl32(pb); - fps_num = get_le32(pb); - fps_den = get_le32(pb); + fps_num = avio_rl32(pb); + fps_den = avio_rl32(pb); if (fps_num == 0 || fps_den == 0) { - av_log(s, AV_LOG_ERROR, "invalid header: invalid fps (%d/%d)\n", fps_num, fps_den); + av_log(s, AV_LOG_ERROR, + "invalid header: invalid fps (%"PRIu32"/%"PRIu32")\n", + fps_num, fps_den); return AVERROR(EIO); } - av_set_pts_info(vst, 64, fps_den, fps_num); + avpriv_set_pts_info(vst, 64, fps_den, fps_num); + vst->avg_frame_rate = av_inv_q(vst->time_base); vst->codec->codec_type = AVMEDIA_TYPE_VIDEO; - vst->codec->codec_id = CODEC_ID_BINKVIDEO; + vst->codec->codec_id = AV_CODEC_ID_BINKVIDEO; vst->codec->extradata = av_mallocz(4 + FF_INPUT_BUFFER_PADDING_SIZE); + if (!vst->codec->extradata) + return AVERROR(ENOMEM); vst->codec->extradata_size = 4; - get_buffer(pb, vst->codec->extradata, 4); + avio_read(pb, vst->codec->extradata, 4); - bink->num_audio_tracks = get_le32(pb); + bink->num_audio_tracks = avio_rl32(pb); if (bink->num_audio_tracks > BINK_MAX_AUDIO_TRACKS) { av_log(s, AV_LOG_ERROR, - "invalid header: more than "AV_STRINGIFY(BINK_MAX_AUDIO_TRACKS)" audio tracks (%d)\n", + "invalid header: more than "AV_STRINGIFY(BINK_MAX_AUDIO_TRACKS)" audio tracks (%"PRIu32")\n", bink->num_audio_tracks); return AVERROR(EIO); } if (bink->num_audio_tracks) { - url_fskip(pb, 4 * bink->num_audio_tracks); + avio_skip(pb, 4 * bink->num_audio_tracks); for (i = 0; i < bink->num_audio_tracks; i++) { - ast = av_new_stream(s, 1); + ast = avformat_new_stream(s, NULL); if (!ast) return AVERROR(ENOMEM); ast->codec->codec_type = AVMEDIA_TYPE_AUDIO; ast->codec->codec_tag = 0; - ast->codec->sample_rate = get_le16(pb); - av_set_pts_info(ast, 64, 1, ast->codec->sample_rate); - flags = get_le16(pb); + ast->codec->sample_rate = avio_rl16(pb); + avpriv_set_pts_info(ast, 64, 1, ast->codec->sample_rate); + flags = avio_rl16(pb); ast->codec->codec_id = flags & BINK_AUD_USEDCT ? - CODEC_ID_BINKAUDIO_DCT : CODEC_ID_BINKAUDIO_RDFT; - ast->codec->channels = flags & BINK_AUD_STEREO ? 2 : 1; + AV_CODEC_ID_BINKAUDIO_DCT : AV_CODEC_ID_BINKAUDIO_RDFT; + if (flags & BINK_AUD_STEREO) { + ast->codec->channels = 2; + ast->codec->channel_layout = AV_CH_LAYOUT_STEREO; + } else { + ast->codec->channels = 1; + ast->codec->channel_layout = AV_CH_LAYOUT_MONO; + } + ast->codec->extradata = av_mallocz(4 + FF_INPUT_BUFFER_PADDING_SIZE); + if (!ast->codec->extradata) + return AVERROR(ENOMEM); + ast->codec->extradata_size = 4; + AV_WL32(ast->codec->extradata, vst->codec->codec_tag); } - url_fskip(pb, 4 * bink->num_audio_tracks); + for (i = 0; i < bink->num_audio_tracks; i++) + s->streams[i + 1]->id = avio_rl32(pb); } /* frame index table */ - next_pos = get_le32(pb); + next_pos = avio_rl32(pb); for (i = 0; i < vst->duration; i++) { pos = next_pos; if (i == vst->duration - 1) { next_pos = bink->file_size; keyframe = 0; } else { - next_pos = get_le32(pb); + next_pos = avio_rl32(pb); keyframe = pos & 1; } pos &= ~1; @@ -168,7 +189,7 @@ static int read_header(AVFormatContext *s, AVFormatParameters *ap) keyframe ? AVINDEX_KEYFRAME : 0); } - url_fskip(pb, 4); + avio_skip(pb, 4); bink->current_track = -1; return 0; @@ -177,7 +198,7 @@ static int read_header(AVFormatContext *s, AVFormatParameters *ap) static int read_packet(AVFormatContext *s, AVPacket *pkt) { BinkDemuxContext *bink = s->priv_data; - ByteIOContext *pb = s->pb; + AVIOContext *pb = s->pb; int ret; if (bink->current_track < 0) { @@ -201,10 +222,10 @@ static int read_packet(AVFormatContext *s, AVPacket *pkt) } while (bink->current_track < bink->num_audio_tracks) { - uint32_t audio_size = get_le32(pb); + uint32_t audio_size = avio_rl32(pb); if (audio_size > bink->remain_packet_size - 4) { av_log(s, AV_LOG_ERROR, - "frame %"PRId64": audio size in header (%u) > size of packet left (%u)\n", + "frame %"PRId64": audio size in header (%"PRIu32") > size of packet left (%"PRIu32")\n", bink->video_pts, audio_size, bink->remain_packet_size); return AVERROR(EIO); } @@ -224,7 +245,7 @@ static int read_packet(AVFormatContext *s, AVPacket *pkt) AV_RL32(pkt->data) / (2 * s->streams[bink->current_track]->codec->channels); return 0; } else { - url_fseek(pb, audio_size, SEEK_CUR); + avio_skip(pb, audio_size); } } @@ -233,7 +254,7 @@ static int read_packet(AVFormatContext *s, AVPacket *pkt) return ret; pkt->stream_index = 0; pkt->pts = bink->video_pts++; - pkt->flags |= PKT_FLAG_KEY; + pkt->flags |= AV_PKT_FLAG_KEY; /* -1 instructs the next call to read_packet() to read the next frame */ bink->current_track = -1; @@ -246,24 +267,25 @@ static int read_seek(AVFormatContext *s, int stream_index, int64_t timestamp, in BinkDemuxContext *bink = s->priv_data; AVStream *vst = s->streams[0]; - if (url_is_streamed(s->pb)) + if (!s->pb->seekable) return -1; /* seek to the first frame */ - url_fseek(s->pb, vst->index_entries[0].pos, SEEK_SET); + if (avio_seek(s->pb, vst->index_entries[0].pos, SEEK_SET) < 0) + return -1; + bink->video_pts = 0; memset(bink->audio_pts, 0, sizeof(bink->audio_pts)); bink->current_track = -1; return 0; } -AVInputFormat bink_demuxer = { - "bink", - NULL_IF_CONFIG_SMALL("Bink"), - sizeof(BinkDemuxContext), - probe, - read_header, - read_packet, - NULL, - read_seek, +AVInputFormat ff_bink_demuxer = { + .name = "bink", + .long_name = NULL_IF_CONFIG_SMALL("Bink"), + .priv_data_size = sizeof(BinkDemuxContext), + .read_probe = probe, + .read_header = read_header, + .read_packet = read_packet, + .read_seek = read_seek, };