| 1 | /* |
|---|
| 2 | * FFmpegUtils.c |
|---|
| 3 | * Created by Alexander Strange on 11/7/10. |
|---|
| 4 | * |
|---|
| 5 | * This file is part of Perian. |
|---|
| 6 | * |
|---|
| 7 | * This library 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 | * This library 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 | /* |
|---|
| 23 | * FFmpeg API interfaces and such |
|---|
| 24 | */ |
|---|
| 25 | |
|---|
| 26 | #include "FFmpegUtils.h" |
|---|
| 27 | #include "CommonUtils.h" |
|---|
| 28 | #include "Codecprintf.h" |
|---|
| 29 | #include <pthread.h> |
|---|
| 30 | #include "avformat.h" |
|---|
| 31 | |
|---|
| 32 | void FFAVCodecContextToASBD(AVCodecContext *avctx, AudioStreamBasicDescription *asbd) |
|---|
| 33 | { |
|---|
| 34 | asbd->mFormatID = avctx->codec_tag; |
|---|
| 35 | asbd->mSampleRate = avctx->sample_rate; |
|---|
| 36 | asbd->mChannelsPerFrame = avctx->channels; |
|---|
| 37 | asbd->mBytesPerPacket = avctx->block_align; |
|---|
| 38 | asbd->mFramesPerPacket = avctx->frame_size; |
|---|
| 39 | asbd->mBitsPerChannel = avctx->bits_per_coded_sample; |
|---|
| 40 | } |
|---|
| 41 | |
|---|
| 42 | void FFASBDToAVCodecContext(AudioStreamBasicDescription *asbd, AVCodecContext *avctx) |
|---|
| 43 | { |
|---|
| 44 | avctx->codec_tag = asbd->mFormatID; |
|---|
| 45 | avctx->sample_rate = asbd->mSampleRate; |
|---|
| 46 | avctx->channels = asbd->mChannelsPerFrame; |
|---|
| 47 | avctx->block_align = asbd->mBytesPerPacket; |
|---|
| 48 | avctx->frame_size = asbd->mFramesPerPacket; |
|---|
| 49 | avctx->bits_per_coded_sample = asbd->mBitsPerChannel; |
|---|
| 50 | } |
|---|
| 51 | |
|---|
| 52 | static int PerianLockMgrCallback(void **mutex, enum AVLockOp op) |
|---|
| 53 | { |
|---|
| 54 | pthread_mutex_t **m = (pthread_mutex_t **)mutex; |
|---|
| 55 | int ret = 0; |
|---|
| 56 | |
|---|
| 57 | switch (op) { |
|---|
| 58 | case AV_LOCK_CREATE: |
|---|
| 59 | *m = malloc(sizeof(pthread_mutex_t)); |
|---|
| 60 | ret = pthread_mutex_init(*m, NULL); |
|---|
| 61 | break; |
|---|
| 62 | case AV_LOCK_OBTAIN: |
|---|
| 63 | ret = pthread_mutex_lock(*m); |
|---|
| 64 | break; |
|---|
| 65 | case AV_LOCK_RELEASE: |
|---|
| 66 | ret = pthread_mutex_unlock(*m); |
|---|
| 67 | break; |
|---|
| 68 | case AV_LOCK_DESTROY: |
|---|
| 69 | ret = pthread_mutex_destroy(*m); |
|---|
| 70 | free(*m); |
|---|
| 71 | } |
|---|
| 72 | |
|---|
| 73 | return ret; |
|---|
| 74 | } |
|---|
| 75 | |
|---|
| 76 | #define REGISTER_MUXER(x) { \ |
|---|
| 77 | extern AVOutputFormat x##_muxer; \ |
|---|
| 78 | av_register_output_format(&x##_muxer); } |
|---|
| 79 | #define REGISTER_DEMUXER(x) { \ |
|---|
| 80 | extern AVInputFormat x##_demuxer; \ |
|---|
| 81 | av_register_input_format(&x##_demuxer); } |
|---|
| 82 | #define REGISTER_MUXDEMUX(x) REGISTER_MUXER(x); REGISTER_DEMUXER(x) |
|---|
| 83 | #define REGISTER_PROTOCOL(x) { \ |
|---|
| 84 | extern URLProtocol x##_protocol; \ |
|---|
| 85 | register_protocol(&x##_protocol); } |
|---|
| 86 | |
|---|
| 87 | #define REGISTER_ENCODER(x) { \ |
|---|
| 88 | extern AVCodec x##_encoder; \ |
|---|
| 89 | register_avcodec(&x##_encoder); } |
|---|
| 90 | #define REGISTER_DECODER(x) { \ |
|---|
| 91 | extern AVCodec x##_decoder; \ |
|---|
| 92 | avcodec_register(&x##_decoder); } |
|---|
| 93 | #define REGISTER_ENCDEC(x) REGISTER_ENCODER(x); REGISTER_DECODER(x) |
|---|
| 94 | |
|---|
| 95 | #define REGISTER_PARSER(x) { \ |
|---|
| 96 | extern AVCodecParser x##_parser; \ |
|---|
| 97 | av_register_codec_parser(&x##_parser); } |
|---|
| 98 | #define REGISTER_BSF(x) { \ |
|---|
| 99 | extern AVBitStreamFilter x##_bsf; \ |
|---|
| 100 | av_register_bitstream_filter(&x##_bsf); } |
|---|
| 101 | |
|---|
| 102 | void FFInitFFmpeg() |
|---|
| 103 | { |
|---|
| 104 | /* This one is used because Global variables are initialized ONE time |
|---|
| 105 | * until the application quits. Thus, we have to make sure we're initialize |
|---|
| 106 | * the libavformat only once or we get an endlos loop when registering the same |
|---|
| 107 | * element twice!! */ |
|---|
| 108 | static Boolean inited = FALSE; |
|---|
| 109 | int unlock = PerianInitEnter(&inited); |
|---|
| 110 | |
|---|
| 111 | /* Register the Parser of ffmpeg, needed because we do no proper setup of the libraries */ |
|---|
| 112 | if(!inited) { |
|---|
| 113 | inited = TRUE; |
|---|
| 114 | avcodec_init(); |
|---|
| 115 | av_lockmgr_register(PerianLockMgrCallback); |
|---|
| 116 | |
|---|
| 117 | REGISTER_DEMUXER(avi); |
|---|
| 118 | REGISTER_DEMUXER(flv); |
|---|
| 119 | REGISTER_DEMUXER(tta); |
|---|
| 120 | REGISTER_DEMUXER(nuv); |
|---|
| 121 | REGISTER_PARSER(ac3); |
|---|
| 122 | REGISTER_PARSER(mpegaudio); |
|---|
| 123 | |
|---|
| 124 | REGISTER_DECODER(msmpeg4v1); |
|---|
| 125 | REGISTER_DECODER(msmpeg4v2); |
|---|
| 126 | REGISTER_DECODER(msmpeg4v3); |
|---|
| 127 | REGISTER_DECODER(mpeg4); |
|---|
| 128 | REGISTER_DECODER(h264); |
|---|
| 129 | REGISTER_DECODER(flv); |
|---|
| 130 | REGISTER_DECODER(flashsv); |
|---|
| 131 | REGISTER_DECODER(vp3); |
|---|
| 132 | REGISTER_DECODER(vp6); |
|---|
| 133 | REGISTER_DECODER(vp6f); |
|---|
| 134 | REGISTER_DECODER(vp8); |
|---|
| 135 | REGISTER_DECODER(h263i); |
|---|
| 136 | REGISTER_DECODER(huffyuv); |
|---|
| 137 | REGISTER_DECODER(ffvhuff); |
|---|
| 138 | REGISTER_DECODER(mpeg1video); |
|---|
| 139 | REGISTER_DECODER(mpeg2video); |
|---|
| 140 | REGISTER_DECODER(fraps); |
|---|
| 141 | REGISTER_DECODER(snow); |
|---|
| 142 | REGISTER_DECODER(nuv); |
|---|
| 143 | REGISTER_DECODER(ffv1); |
|---|
| 144 | REGISTER_DECODER(theora); |
|---|
| 145 | |
|---|
| 146 | REGISTER_DECODER(wmav1); |
|---|
| 147 | REGISTER_DECODER(wmav2); |
|---|
| 148 | REGISTER_DECODER(adpcm_swf); |
|---|
| 149 | REGISTER_DECODER(vorbis); |
|---|
| 150 | REGISTER_DECODER(mp1); |
|---|
| 151 | REGISTER_DECODER(mp2); |
|---|
| 152 | REGISTER_DECODER(tta); |
|---|
| 153 | REGISTER_DECODER(dca); |
|---|
| 154 | REGISTER_DECODER(nellymoser); |
|---|
| 155 | |
|---|
| 156 | REGISTER_DECODER(dvdsub); |
|---|
| 157 | REGISTER_DECODER(tscc); |
|---|
| 158 | REGISTER_DECODER(vp6a); |
|---|
| 159 | REGISTER_DECODER(zmbv); |
|---|
| 160 | REGISTER_DECODER(indeo2); |
|---|
| 161 | REGISTER_DECODER(indeo3); |
|---|
| 162 | REGISTER_DECODER(indeo5); |
|---|
| 163 | |
|---|
| 164 | av_log_set_callback(FFMpegCodecprintf); |
|---|
| 165 | } |
|---|
| 166 | |
|---|
| 167 | PerianInitExit(unlock); |
|---|
| 168 | } |
|---|