28 #include <libavformat/avformat.h>
29 #include <libavcodec/avcodec.h>
30 #include <libavutil/avutil.h>
31 #include <libavutil/dict.h>
32 #include <libavutil/mathematics.h>
33 #include <libswscale/swscale.h>
35 static int32_t avbin_thread_count = 1;
55 static void avbin_log_callback(
void *ptr,
60 static char message[8192];
61 const char *module = NULL;
64 if (level > av_log_get_level() || !user_log_callback)
69 AVClass *avc = *(AVClass**) ptr;
70 module = avc->item_name(ptr);
73 vsnprintf(message,
sizeof message, fmt, vl);
90 info->
repo = AVBIN_REPO;
91 info->
commit = AVBIN_COMMIT;
106 return AVCODEC_MAX_AUDIO_FRAME_SIZE;
111 if (strcmp(feature,
"frame_rate") == 0)
113 if (strcmp(feature,
"options") == 0)
115 if (strcmp(feature,
"info") == 0)
127 if (options_ptr == NULL)
129 options_ptr = malloc(
sizeof(options_ptr));
130 if (options_ptr == NULL)
142 options = options_ptr;
154 avcodec_register_all();
161 av_log_set_level(level);
167 user_log_callback = callback;
174 av_log_set_callback(avbin_log_callback);
176 av_log_set_callback(av_log_default_callback);
185 AVInputFormat *avformat = NULL;
186 if (format) avformat = av_find_input_format(format);
189 if (avformat_open_input(&file->
context, filename, avformat, NULL) != 0)
192 if (avformat_find_stream_info(file->
context, NULL) < 0)
207 av_free_packet(file->
packet);
211 avformat_close_input(&file->
context);
218 AVCodecContext *codec_context;
221 av_seek_frame(file->
context, -1, 0,
222 AVSEEK_FLAG_ANY | AVSEEK_FLAG_BYTE);
224 av_seek_frame(file->
context, -1, timestamp, 0);
226 for (i = 0; i < file->
context->nb_streams; i++)
228 codec_context = file->
context->streams[i]->codec;
230 avcodec_flush_buffers(codec_context);
254 AVDictionaryEntry* entry;
255 if ((entry = av_dict_get(file->
context->metadata,
"title", NULL, 0)) != NULL) {
256 strncpy(info->
title, entry->value,
sizeof(info->
title));
259 if (((entry = av_dict_get(file->
context->metadata,
"artist", NULL, 0)) != NULL) ||
260 (entry = av_dict_get(file->
context->metadata,
"album_artist", NULL, 0)) != NULL) {
261 strncpy(info->
author, entry->value,
sizeof(info->
author));
263 if ((entry = av_dict_get(file->
context->metadata,
"copyright", NULL, 0)) != NULL) {
266 if ((entry = av_dict_get(file->
context->metadata,
"comment", NULL, 0)) != NULL) {
269 if ((entry = av_dict_get(file->
context->metadata,
"album", NULL, 0)) != NULL) {
270 strncpy(info->
album, entry->value,
sizeof(info->
album));
272 if ((entry = av_dict_get(file->
context->metadata,
"date", NULL, 0)) != NULL) {
273 info->
year = atoi(entry->value);
275 if ((entry = av_dict_get(file->
context->metadata,
"track", NULL, 0)) != NULL) {
276 info->
track = atoi(entry->value);
278 if ((entry = av_dict_get(file->
context->metadata,
"genre", NULL, 0)) != NULL) {
279 strncpy(info->
genre, entry->value,
sizeof(info->
genre));
288 AVCodecContext *context = file->
context->streams[stream_index]->codec;
299 switch (context->codec_type)
301 case AVMEDIA_TYPE_VIDEO:
303 info->
video.width = context->width;
304 info->
video.height = context->height;
305 info->
video.sample_aspect_num = context->sample_aspect_ratio.num;
306 info->
video.sample_aspect_den = context->sample_aspect_ratio.den;
309 AVRational frame_rate = \
310 file->context->streams[stream_index]->r_frame_rate;
311 info_8->
video.frame_rate_num = frame_rate.num;
312 info_8->
video.frame_rate_den = frame_rate.den;
317 if (info_8->
video.frame_rate_num /
318 info_8->
video.frame_rate_den > 1000)
319 info_8->
video.frame_rate_den *= 1000;
322 case AVMEDIA_TYPE_AUDIO:
324 info->
audio.sample_rate = context->sample_rate;
325 info->
audio.channels = context->channels;
326 switch (context->sample_fmt)
328 case AV_SAMPLE_FMT_U8:
330 info->
audio.sample_bits = 8;
332 case AV_SAMPLE_FMT_S16:
334 info->
audio.sample_bits = 16;
336 case AV_SAMPLE_FMT_S32:
338 info->
audio.sample_bits = 32;
340 case AV_SAMPLE_FMT_FLT:
342 info->
audio.sample_bits = 32;
346 info->
audio.sample_format = -1;
347 info->
audio.sample_bits = -1;
364 AVCodecContext *codec_context;
367 if (index < 0 || index >= file->
context->nb_streams)
370 codec_context = file->
context->streams[index]->codec;
371 codec = avcodec_find_decoder(codec_context->codec_id);
375 if (avbin_thread_count != 1)
376 codec_context->thread_count = avbin_thread_count;
378 if (avcodec_open2(codec_context, codec, NULL) < 0)
384 stream->
type = codec_context->codec_type;
385 if (stream->
type == AVMEDIA_TYPE_VIDEO)
386 stream->
frame = avcodec_alloc_frame();
388 stream->
frame = NULL;
395 av_free(stream->
frame);
406 av_free_packet(file->
packet);
414 file->
context->streams[file->
packet->stream_index]->time_base,
424 uint8_t *data_in,
size_t size_in,
425 uint8_t *data_out,
int *size_out)
428 if (stream->
type != AVMEDIA_TYPE_AUDIO)
432 av_init_packet(&packet);
433 packet.data = data_in;
434 packet.size = size_in;
438 used = avcodec_decode_audio4(stream->
codec_context, &frame, &got_frame, &packet);
444 if (used >= 0 && got_frame) {
446 int data_size = av_samples_get_buffer_size(&plane_size,
450 if (*size_out < data_size) {
451 av_log(stream->
codec_context, AV_LOG_ERROR,
"Output audio buffer is too small for current audio frame!");
455 memcpy(data_out, frame.extended_data[0], data_size);
456 *size_out = data_size;
465 uint8_t *data_in,
size_t size_in,
468 AVPicture picture_rgb;
474 if (stream->
type != AVMEDIA_TYPE_VIDEO)
478 av_init_packet(&packet);
479 packet.data = data_in;
480 packet.size = size_in;
483 stream->
frame, &got_picture,
490 avpicture_fill(&picture_rgb, data_out, PIX_FMT_RGB24, width, height);
491 static struct SwsContext *img_convert_ctx = NULL;
492 img_convert_ctx = sws_getCachedContext(img_convert_ctx,width, height,stream->
codec_context->pix_fmt,width, height,PIX_FMT_RGB24, SWS_FAST_BILINEAR, NULL, NULL, NULL);
493 sws_scale(img_convert_ctx, (
const uint8_t*
const*)stream->
frame->data, stream->
frame->linesize,0, height, picture_rgb.data, picture_rgb.linesize);