00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "avformat.h"
00023 #include "internal.h"
00024 #include "riff.h"
00025
00026 #include <windows.h>
00027 #include <vfw.h>
00028
00029 typedef struct {
00030 PAVISTREAM handle;
00031 AVISTREAMINFO info;
00032 DWORD read;
00033 LONG chunck_size;
00034 LONG chunck_samples;
00035 } AVISynthStream;
00036
00037 typedef struct {
00038 PAVIFILE file;
00039 AVISynthStream *streams;
00040 int nb_streams;
00041 int next_stream;
00042 } AVISynthContext;
00043
00044 static int avisynth_read_header(AVFormatContext *s)
00045 {
00046 AVISynthContext *avs = s->priv_data;
00047 HRESULT res;
00048 AVIFILEINFO info;
00049 DWORD id;
00050 AVStream *st;
00051 AVISynthStream *stream;
00052 wchar_t filename_wchar[1024] = { 0 };
00053 char filename_char[1024] = { 0 };
00054
00055 AVIFileInit();
00056
00057
00058 MultiByteToWideChar(CP_UTF8, 0, s->filename, -1, filename_wchar, 1024);
00059 WideCharToMultiByte(CP_THREAD_ACP, 0, filename_wchar, -1, filename_char, 1024, NULL, NULL);
00060 res = AVIFileOpen(&avs->file, filename_char, OF_READ|OF_SHARE_DENY_WRITE, NULL);
00061 if (res != S_OK)
00062 {
00063 av_log(s, AV_LOG_ERROR, "AVIFileOpen failed with error %ld\n", res);
00064 AVIFileExit();
00065 return -1;
00066 }
00067
00068 res = AVIFileInfo(avs->file, &info, sizeof(info));
00069 if (res != S_OK)
00070 {
00071 av_log(s, AV_LOG_ERROR, "AVIFileInfo failed with error %ld\n", res);
00072 AVIFileExit();
00073 return -1;
00074 }
00075
00076 avs->streams = av_mallocz(info.dwStreams * sizeof(AVISynthStream));
00077
00078 for (id=0; id<info.dwStreams; id++)
00079 {
00080 stream = &avs->streams[id];
00081 stream->read = 0;
00082 if (AVIFileGetStream(avs->file, &stream->handle, 0, id) == S_OK)
00083 {
00084 if (AVIStreamInfo(stream->handle, &stream->info, sizeof(stream->info)) == S_OK)
00085 {
00086 if (stream->info.fccType == streamtypeAUDIO)
00087 {
00088 WAVEFORMATEX wvfmt;
00089 LONG struct_size = sizeof(WAVEFORMATEX);
00090 if (AVIStreamReadFormat(stream->handle, 0, &wvfmt, &struct_size) != S_OK)
00091 continue;
00092
00093 st = avformat_new_stream(s, NULL);
00094 st->id = id;
00095 st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
00096
00097 st->codec->block_align = wvfmt.nBlockAlign;
00098 st->codec->channels = wvfmt.nChannels;
00099 st->codec->sample_rate = wvfmt.nSamplesPerSec;
00100 st->codec->bit_rate = wvfmt.nAvgBytesPerSec * 8;
00101 st->codec->bits_per_coded_sample = wvfmt.wBitsPerSample;
00102
00103 stream->chunck_samples = wvfmt.nSamplesPerSec * (uint64_t)info.dwScale / (uint64_t)info.dwRate;
00104 stream->chunck_size = stream->chunck_samples * wvfmt.nChannels * wvfmt.wBitsPerSample / 8;
00105
00106 st->codec->codec_tag = wvfmt.wFormatTag;
00107 st->codec->codec_id = ff_wav_codec_get_id(wvfmt.wFormatTag, st->codec->bits_per_coded_sample);
00108 }
00109 else if (stream->info.fccType == streamtypeVIDEO)
00110 {
00111 BITMAPINFO imgfmt;
00112 LONG struct_size = sizeof(BITMAPINFO);
00113
00114 stream->chunck_size = stream->info.dwSampleSize;
00115 stream->chunck_samples = 1;
00116
00117 if (AVIStreamReadFormat(stream->handle, 0, &imgfmt, &struct_size) != S_OK)
00118 continue;
00119
00120 st = avformat_new_stream(s, NULL);
00121 st->id = id;
00122 st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
00123 st->avg_frame_rate.num = stream->info.dwRate;
00124 st->avg_frame_rate.den = stream->info.dwScale;
00125 #if FF_API_R_FRAME_RATE
00126 st->r_frame_rate = st->avg_frame_rate;
00127 #endif
00128
00129 st->codec->width = imgfmt.bmiHeader.biWidth;
00130 st->codec->height = imgfmt.bmiHeader.biHeight;
00131
00132 st->codec->bits_per_coded_sample = imgfmt.bmiHeader.biBitCount;
00133 st->codec->bit_rate = (uint64_t)stream->info.dwSampleSize * (uint64_t)stream->info.dwRate * 8 / (uint64_t)stream->info.dwScale;
00134 st->codec->codec_tag = imgfmt.bmiHeader.biCompression;
00135 st->codec->codec_id = ff_codec_get_id(ff_codec_bmp_tags, imgfmt.bmiHeader.biCompression);
00136 if (st->codec->codec_id == AV_CODEC_ID_RAWVIDEO && imgfmt.bmiHeader.biCompression== BI_RGB) {
00137 st->codec->extradata = av_malloc(9 + FF_INPUT_BUFFER_PADDING_SIZE);
00138 if (st->codec->extradata) {
00139 st->codec->extradata_size = 9;
00140 memcpy(st->codec->extradata, "BottomUp", 9);
00141 }
00142 }
00143
00144
00145 st->duration = stream->info.dwLength;
00146 }
00147 else
00148 {
00149 AVIStreamRelease(stream->handle);
00150 continue;
00151 }
00152
00153 avs->nb_streams++;
00154
00155 st->codec->stream_codec_tag = stream->info.fccHandler;
00156
00157 avpriv_set_pts_info(st, 64, info.dwScale, info.dwRate);
00158 st->start_time = stream->info.dwStart;
00159 }
00160 }
00161 }
00162
00163 return 0;
00164 }
00165
00166 static int avisynth_read_packet(AVFormatContext *s, AVPacket *pkt)
00167 {
00168 AVISynthContext *avs = s->priv_data;
00169 HRESULT res;
00170 AVISynthStream *stream;
00171 int stream_id = avs->next_stream;
00172 LONG read_size;
00173
00174
00175 stream = &avs->streams[stream_id];
00176
00177 if (stream->read >= stream->info.dwLength)
00178 return AVERROR(EIO);
00179
00180 if (av_new_packet(pkt, stream->chunck_size))
00181 return AVERROR(EIO);
00182 pkt->stream_index = stream_id;
00183 pkt->pts = avs->streams[stream_id].read / avs->streams[stream_id].chunck_samples;
00184
00185 res = AVIStreamRead(stream->handle, stream->read, stream->chunck_samples, pkt->data, stream->chunck_size, &read_size, NULL);
00186
00187 pkt->size = read_size;
00188
00189 stream->read += stream->chunck_samples;
00190
00191
00192 do {
00193 avs->next_stream = (avs->next_stream+1) % avs->nb_streams;
00194 } while (avs->next_stream != stream_id && s->streams[avs->next_stream]->discard >= AVDISCARD_ALL);
00195
00196 return (res == S_OK) ? pkt->size : -1;
00197 }
00198
00199 static int avisynth_read_close(AVFormatContext *s)
00200 {
00201 AVISynthContext *avs = s->priv_data;
00202 int i;
00203
00204 for (i=0;i<avs->nb_streams;i++)
00205 {
00206 AVIStreamRelease(avs->streams[i].handle);
00207 }
00208
00209 av_free(avs->streams);
00210 AVIFileRelease(avs->file);
00211 AVIFileExit();
00212 return 0;
00213 }
00214
00215 static int avisynth_read_seek(AVFormatContext *s, int stream_index, int64_t pts, int flags)
00216 {
00217 AVISynthContext *avs = s->priv_data;
00218 int stream_id;
00219
00220 for (stream_id = 0; stream_id < avs->nb_streams; stream_id++)
00221 {
00222 avs->streams[stream_id].read = pts * avs->streams[stream_id].chunck_samples;
00223 }
00224
00225 return 0;
00226 }
00227
00228 AVInputFormat ff_avisynth_demuxer = {
00229 .name = "avs",
00230 .long_name = NULL_IF_CONFIG_SMALL("AVISynth"),
00231 .priv_data_size = sizeof(AVISynthContext),
00232 .read_header = avisynth_read_header,
00233 .read_packet = avisynth_read_packet,
00234 .read_close = avisynth_read_close,
00235 .read_seek = avisynth_read_seek,
00236 .extensions = "avs",
00237 };