Mercurial > pt1.oyama
diff libdlna-0.2.3/src/av_wmv9.c @ 129:4f6d9621ee00
add multi session streaming & add depending librarys.
- libupnp-1.6.6
- libdlna-0.2.3
author | Naoya OYAMA <naoya.oyama@gmail.com> |
---|---|
date | Sun, 10 Oct 2010 15:33:18 +0900 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libdlna-0.2.3/src/av_wmv9.c Sun Oct 10 15:33:18 2010 +0900 @@ -0,0 +1,276 @@ +/* + * libdlna: reference DLNA standards implementation. + * Copyright (C) 2007 Benjamin Zores <ben@geexbox.org> + * + * This file is part of libdlna. + * + * libdlna 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. + * + * libdlna 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 libdlna; if not, write to the Free Software + * Foundation, Inc, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* Summary of VMW9 Profiles + * Simple and Main profiles are identified by FourCC WMV3 + * Advanced profile is identified by FourCC WVC1 + * + * Profile Level Max. Bitrate Format + * + * Simple Low 96 Kbps 176 x 144 @ 15 Hz (QCIF) + * Medium 384 Kbps 240 x 176 @ 30 Hz + * 352 x 288 @ 15 Hz (CIF) + * + * Main Low 2 Mbps 320 x 240 @ 24 Hz (QVGA) + * Medium 10 Mbps 720 x 480 @ 30 Hz (480p) + * 720 x 576 @ 25 Hz (576p) + * High 20 Mbps 1920 x 1080 @ 30 Hz (1080p) + * + * Advanced L0 2 Mbps 352 x 288 @ 30 Hz (CIF) + * L1 10 Mbps 720 x 480 @ 30 Hz (NTSC-SD) + * 720 x 576 @ 25 Hz (PAL-SD) + * L2 20 Mbps 720 x 480 @ 60 Hz (480p) + * 1280 x 720 @ 30 Hz (720p) + * L3 45 Mbps 1920 x 1080 @ 24 Hz (1080p) + * 1920 x 1080 @ 30 Hz (1080i) + * 1280 x 720 @ 60 Hz (720p) + * L4 135 Mbps 1920 x 1080 @ 60 Hz (1080p) + * 2048 x 1536 @ 24 Hz + */ + +#include <stdlib.h> +#include <string.h> + +#include "dlna_internals.h" +#include "profiles.h" +#include "containers.h" + +typedef enum { + WMV_VIDEO_PROFILE_INVALID, + WMV_VIDEO_PROFILE_SIMPLE_LOW, + WMV_VIDEO_PROFILE_SIMPLE_MEDIUM, + WMV_VIDEO_PROFILE_MAIN_MEDIUM, + WMV_VIDEO_PROFILE_MAIN_HIGH +} wmv_video_profile_t; + +typedef struct wmv9_profile_s { + int max_width; + int max_height; + int fps_num; + int fps_den; + int max_bitrate; +} wmv9_profile_t; + +static wmv9_profile_t wmv9_profile_simple_low[] = { + { 176, 144, 15, 1, 96000} +}; + +static wmv9_profile_t wmv9_profile_simple_medium[] = { + { 240, 176, 30, 1, 384000}, + { 240, 176, 30000, 1001, 384000}, + { 352, 288, 15, 1, 384000} +}; + +static wmv9_profile_t wmv9_profile_main_medium[] = { + { 720, 480, 30, 1, 10000000}, + { 720, 480, 30000, 1001, 10000000}, + { 720, 576, 25, 1, 10000000} +}; + +static wmv9_profile_t wmv9_profile_main_high[] = { + { 1920, 1080, 30, 1, 20000000}, + { 1920, 1080, 30000, 1001, 20000000} +}; + +/* Medium resolution video (Main profile at Medium Level) + with baseline WMA audio */ +static dlna_profile_t wmvmed_base = { + .id = "WMVMED_BASE", + .mime = MIME_VIDEO_WMV, + .label = LABEL_VIDEO_SD +}; + +/* Medium resolution video (Main profile at Medium Level) + with full WMA audio */ +static dlna_profile_t wmvmed_full = { + .id = "WMVMED_FULL", + .mime = MIME_VIDEO_WMV, + .label = LABEL_VIDEO_SD +}; + +/* Medium resolution video (Main profile at Medium Level) + with WMA professional audio */ +static dlna_profile_t wmvmed_pro = { + .id = "WMVMED_PRO", + .mime = MIME_VIDEO_WMV, + .label = LABEL_VIDEO_HD +}; + +/* High resolution video (Main profile at High Level) + with full WMA audio */ +static dlna_profile_t wmvhigh_full = { + .id = "WMVHIGH_FULL", + .mime = MIME_VIDEO_WMV, + .label = LABEL_VIDEO_HD +}; + +/* High resolution video (Main profile at High Level) + with WMA professional audio */ +static dlna_profile_t wmvhigh_pro = { + .id = "WMVHIGH_PRO", + .mime = MIME_VIDEO_WMV, + .label = LABEL_VIDEO_HD +}; + +/* HighMAT profile */ +static dlna_profile_t wmvhm_base dlna_unused = { + .id = "WMVHM_BASE", + .mime = MIME_VIDEO_WMV, + .label = LABEL_VIDEO_SD +}; + +/* Low resolution video (Simple Profile at Low Level) + with baseline WMA audio */ +static dlna_profile_t wmvspll_base = { + .id = "WMVSPLL_BASE", + .mime = MIME_VIDEO_WMV, + .label = LABEL_VIDEO_QCIF15 +}; + +/* Low resolution video (Simple Profile at Medium Level) + with baseline WMA audio */ +static dlna_profile_t wmvspml_base = { + .id = "WMVSPML_BASE", + .mime = MIME_VIDEO_WMV, + .label = LABEL_VIDEO_CIF15 +}; + +/* Low resolution video (Simple Profile at Medium Level) with MP3 audio */ +static dlna_profile_t wmvspml_mp3 = { + .id = "WMVSPML_MP3", + .mime = MIME_VIDEO_WMV, + .label = LABEL_VIDEO_CIF15 +}; + +static const struct { + dlna_profile_t *profile; + wmv_video_profile_t vp; + audio_profile_t ap; +} wmv_profiles_mapping[] = { + { &wmvmed_base, WMV_VIDEO_PROFILE_MAIN_MEDIUM, + AUDIO_PROFILE_WMA_BASELINE }, + { &wmvmed_full, WMV_VIDEO_PROFILE_MAIN_MEDIUM, + AUDIO_PROFILE_WMA_FULL }, + { &wmvmed_pro, WMV_VIDEO_PROFILE_MAIN_MEDIUM, + AUDIO_PROFILE_WMA_PRO }, + { &wmvhigh_full, WMV_VIDEO_PROFILE_MAIN_HIGH, + AUDIO_PROFILE_WMA_FULL }, + { &wmvhigh_pro, WMV_VIDEO_PROFILE_MAIN_HIGH, + AUDIO_PROFILE_WMA_FULL }, + { &wmvspll_base, WMV_VIDEO_PROFILE_SIMPLE_LOW, + AUDIO_PROFILE_WMA_BASELINE }, + { &wmvspml_base, WMV_VIDEO_PROFILE_SIMPLE_MEDIUM, + AUDIO_PROFILE_WMA_BASELINE }, + { &wmvspml_mp3, WMV_VIDEO_PROFILE_SIMPLE_MEDIUM, + AUDIO_PROFILE_MP3 }, + { NULL, 0, 0, } +}; + +static int +is_valid_wmv9_video_profile (wmv9_profile_t profile[], int size, + AVStream *vs, AVCodecContext *vc) +{ + int i; + + for (i = 0; i < size / (int) sizeof (wmv9_profile_t); i++) + if (vc->width <= profile[i].max_width && + vc->height <= profile[i].max_height && + vs->r_frame_rate.num == profile[i].fps_num && + vs->r_frame_rate.den == profile[i].fps_den && + vc->bit_rate <= profile[i].max_bitrate) + return 1; + + /* video properties do not fit the requested profile */ + return 0; +} + +static wmv_video_profile_t +wmv_video_profile_get (AVStream *vs, AVCodecContext *vc) +{ + if (!vs || !vc) + return WMV_VIDEO_PROFILE_INVALID; + + if (is_valid_wmv9_video_profile (wmv9_profile_simple_low, + sizeof (wmv9_profile_simple_low), vs, vc)) + return WMV_VIDEO_PROFILE_SIMPLE_LOW; + + if (is_valid_wmv9_video_profile (wmv9_profile_simple_medium, + sizeof (wmv9_profile_simple_medium), + vs, vc)) + return WMV_VIDEO_PROFILE_SIMPLE_MEDIUM; + + if (is_valid_wmv9_video_profile (wmv9_profile_main_medium, + sizeof (wmv9_profile_main_medium), vs, vc)) + return WMV_VIDEO_PROFILE_MAIN_MEDIUM; + + if (is_valid_wmv9_video_profile (wmv9_profile_main_high, + sizeof (wmv9_profile_main_high), vs, vc)) + return WMV_VIDEO_PROFILE_MAIN_HIGH; + + return WMV_VIDEO_PROFILE_INVALID; +} + +static dlna_profile_t * +probe_wmv9 (AVFormatContext *ctx dlna_unused, + dlna_container_type_t st, + av_codecs_t *codecs) +{ + wmv_video_profile_t vp; + audio_profile_t ap; + int i; + + if (!stream_ctx_is_av (codecs)) + return NULL; + + /* need to be in ASF container only */ + if (st != CT_ASF) + return NULL; + + /* check for WMV3 (Simple and Main profiles) video codec */ + if (codecs->vc->codec_id != CODEC_ID_WMV3) + return NULL; + + /* get video profile */ + vp = wmv_video_profile_get (codecs->vs, codecs->vc); + if (vp == WMV_VIDEO_PROFILE_INVALID) + return NULL; + + /* get audio profile */ + ap = audio_profile_guess (codecs->ac); + if (ap == AUDIO_PROFILE_INVALID) + return NULL; + + /* find profile according to container type, video and audio profiles */ + for (i = 0; wmv_profiles_mapping[i].profile; i++) + if (wmv_profiles_mapping[i].vp == vp && + wmv_profiles_mapping[i].ap == ap) + return wmv_profiles_mapping[i].profile; + + return NULL; +} + +dlna_registered_profile_t dlna_profile_av_wmv9 = { + .id = DLNA_PROFILE_AV_WMV9, + .class = DLNA_CLASS_AV, + .extensions = "asf,wmv", + .probe = probe_wmv9, + .next = NULL +};