Mercurial > pt1.oyama
diff libdlna-0.2.3/src/av_mpeg4_part2.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_mpeg4_part2.c Sun Oct 10 15:33:18 2010 +0900 @@ -0,0 +1,929 @@ +/* + * 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 + */ + +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> + +#include <ffmpeg/avcodec.h> + +#include "dlna_internals.h" +#include "profiles.h" +#include "containers.h" + +typedef enum { + MPEG4_VCODEC_INVALID, + MPEG4_VCODEC_H263, + MPEG4_VCODEC_P2, +} mpeg4_vcodec_type_t; + +static const struct { + int codec_id; + mpeg4_vcodec_type_t type; +} avf_vcodec_mapping[] = { + { CODEC_ID_H263, MPEG4_VCODEC_H263 }, + { CODEC_ID_H263I, MPEG4_VCODEC_H263 }, + { CODEC_ID_H263P, MPEG4_VCODEC_H263 }, + { CODEC_ID_MPEG4, MPEG4_VCODEC_P2 }, + { CODEC_ID_MSMPEG4V1, MPEG4_VCODEC_P2 }, + { CODEC_ID_MSMPEG4V2, MPEG4_VCODEC_P2 }, + { CODEC_ID_MSMPEG4V3, MPEG4_VCODEC_P2 }, + { -1, 0 } +}; + +typedef enum { + MPEG4_VIDEO_PROFILE_INVALID, + MPEG4_VIDEO_PROFILE_H263, + MPEG4_VIDEO_PROFILE_P2_SP_L0B, + MPEG4_VIDEO_PROFILE_P2_SP_L2, + MPEG4_VIDEO_PROFILE_P2_SP_L3, + MPEG4_VIDEO_PROFILE_P2_SP_L3_VGA, + MPEG4_VIDEO_PROFILE_P2_ASP_L4, + MPEG4_VIDEO_PROFILE_P2_ASP_L5 +} mpeg4_video_profile_t; + +typedef struct video_properties_s { + int width; + int height; + int fps_num; + int fps_den; +} video_properties_t; + +/* H263 Resolutions (all <= 15 fps) */ +static video_properties_t profile_h263_res[] = { + { 176, 144, 15, 1 }, /* QCIF */ + { 128, 96, 15, 1 } /* SQCIF */ +}; + +/* MPEG-4 SP L0B Resolutions (all <= 15 fps) */ +static video_properties_t profile_p2_sp_l0b_res[] = { + { 176, 144, 15, 1 }, /* QCIF */ + { 128, 96, 15, 1 } /* SQCIF */ +}; + +/* MPEG-4 SP L2 Resolutions */ +static video_properties_t profile_p2_sp_l2_res[] = { + { 352, 288, 15, 1 }, /* CIF */ + { 320, 240, 15, 1 }, /* QVGA 4:3 */ + { 320, 180, 15, 1 }, /* QVGA 16:9 */ + { 176, 144, 30, 1 }, /* QCIF */ + { 128, 96, 30, 1 } /* SQCIF */ +}; + +/* MPEG-4 SP L3_VGA Resolutions */ +static video_properties_t profile_p2_sp_l3_vga_res[] = { + { 640, 480, 30, 1 }, /* VGA */ + { 640, 360, 30, 1 } /* VGA 16:9 */ +}; + +/* MPEG-4 L3 / CO Resolutions (all <= 30 fps) */ +static video_properties_t profile_p2_sp_l3_co_res[] = { + { 352, 288, 30, 1 }, /* CIF, 625SIF */ + { 352, 240, 30, 1 }, /* 525SIF */ + { 320, 240, 30, 1 }, /* QVGA 4:3 */ + { 320, 180, 30, 1 }, /* QVGA 16:9 */ + { 240, 180, 30, 1 }, /* 1/7 VGA 4:3 */ + { 208, 160, 30, 1 }, /* 1/9 VGA 4:3 */ + { 176, 144, 30, 1 }, /* QCIF,625QCIF */ + { 176, 120, 30, 1 }, /* 525QCIF */ + { 160, 120, 30, 1 }, /* SQVGA 4:3 */ + { 160, 112, 30, 1 }, /* 1/16 VGA 4:3 */ + { 160, 90, 30, 1 }, /* SQVGA 16:9 */ + { 128, 96, 30, 1 } /* SQCIF */ +}; + +/* MPEG-4 ASP L4 SO Resolutions (all <= 30 fps) */ +static video_properties_t profile_p2_asp_l4_res[] = { + { 352, 576, 30, 1 }, /* 625 1/2 D1 */ + { 352, 480, 30, 1 }, /* 525 1/2 D1 */ + { 352, 288, 30, 1 }, /* CIF, 625SIF */ + { 352, 240, 30, 1 }, /* 525SIF */ + { 320, 240, 30, 1 }, /* QVGA 4:3 */ + { 320, 180, 30, 1 }, /* QVGA 16:9 */ + { 240, 180, 30, 1 }, /* 1/7 VGA 4:3 */ + { 208, 160, 30, 1 }, /* 1/9 VGA 4:3 */ + { 176, 144, 30, 1 }, /* QCIF,625QCIF */ + { 176, 120, 30, 1 }, /* 525QCIF */ + { 160, 120, 30, 1 }, /* SQVGA 4:3 */ + { 160, 112, 30, 1 }, /* 1/16 VGA 4:3 */ + { 160, 90, 30, 1 }, /* SQVGA 16:9 */ + { 128, 96, 30, 1 } /* SQCIF */ +}; + +/* MPEG-4 ASP L5 Resolutions (all <= 30 fps) */ +static video_properties_t profile_p2_asp_l5_res[] = { + { 720, 576, 30, 1 }, /* 625 D1 */ + { 720, 480, 30, 1 }, /* 525 D1 */ + { 704, 576, 30, 1 }, /* 625 4SIF */ + { 704, 480, 30, 1 }, /* 525 4SIF */ + { 640, 480, 30, 1 }, /* VGA */ + { 640, 360, 30, 1 }, /* VGA 16:9 */ + { 544, 576, 30, 1 }, /* 625 3/4 D1 */ + { 544, 480, 30, 1 }, /* 525 3/4 D1 */ + { 480, 576, 30, 1 }, /* 625 2/3 D1 */ + { 480, 480, 30, 1 }, /* 525 2/3 D1 */ + { 480, 360, 30, 1 }, /* 9/16 VGA 4:3 */ + { 480, 270, 30, 1 }, /* 9/16 VGA 16:9 */ + { 352, 576, 30, 1 }, /* 625 1/2 D1 */ + { 352, 480, 30, 1 }, /* 525 1/2 D1 */ + { 352, 288, 30, 1 }, /* CIF, 625SIF */ + { 352, 240, 30, 1 }, /* 525SIF */ + { 320, 240, 30, 1 }, /* QVGA 4:3 */ + { 320, 180, 30, 1 }, /* QVGA 16:9 */ + { 240, 180, 30, 1 }, /* 1/7 VGA 4:3 */ + { 208, 160, 30, 1 }, /* 1/9 VGA 4:3 */ + { 176, 144, 30, 1 }, /* QCIF,625QCIF */ + { 176, 120, 30, 1 }, /* 525QCIF */ + { 160, 120, 30, 1 }, /* SQVGA 4:3 */ + { 160, 112, 30, 1 }, /* 1/16 VGA 4:3 */ + { 160, 90, 30, 1 }, /* SQVGA 16:9 */ + { 128, 96, 30, 1 } /* SQCIF */ +}; + +/********************/ +/* MPEG-4 Container */ +/********************/ + +/* Profile for MPEG-4 Part 2 Simple Profile with AAC LC audio, + encapsulated in MP4 */ +static dlna_profile_t mpeg4_p2_mp4_sp_aac = { + .id = "MPEG4_P2_MP4_SP_AAC", + .mime = MIME_VIDEO_MPEG_4, + .label = LABEL_VIDEO_CIF30 +}; + +/* Profile for MPEG-4 Part 2 Simple Profile with HE AAC audio, + encapsulated in MP4 */ +static dlna_profile_t mpeg4_p2_mp4_sp_heaac = { + .id = "MPEG4_P2_MP4_SP_HEAAC", + .mime = MIME_VIDEO_MPEG_4, + .label = LABEL_VIDEO_CIF30 +}; + +/* Profile for MPEG-4 Part 2 Simple Profile with ATRAC3plus audio, + encapsulated in MP4 */ +static dlna_profile_t mpeg4_p2_mp4_sp_atrac3plus = { + .id = "MPEG4_P2_MP4_SP_ATRAC3plus", + .mime = MIME_VIDEO_MPEG_4, + .label = LABEL_VIDEO_CIF30 +}; + +/* Profile for MPEG-4 Part 2 Simple Profile with AAC LTP audio, + encapsulated in MP4 */ +static dlna_profile_t mpeg4_p2_mp4_sp_aac_ltp = { + .id = "MPEG4_P2_MP4_SP_AAC_LTP", + .mime = MIME_VIDEO_MPEG_4, + .label = LABEL_VIDEO_CIF30 +}; + +/* Profile for MPEG-4 Part 2 Simple Profile Level 2 with AAC audio, + encapsulated in MP4 */ +static dlna_profile_t mpeg4_p2_mp4_sp_l2_aac = { + .id = "MPEG4_P2_MP4_SP_L2_AAC", + .mime = MIME_VIDEO_MPEG_4, + .label = LABEL_VIDEO_CIF15 +}; + +/* Profile for MPEG-4 Part 2 Simple Profile Level 2 with AMR audio, + encapsulated in MP4 */ +static dlna_profile_t mpeg4_p2_mp4_sp_l2_amr = { + .id = "MPEG4_P2_MP4_SP_L2_AMR", + .mime = MIME_VIDEO_MPEG_4, + .label = LABEL_VIDEO_CIF15 +}; + +/* Profile for MPEG-4 Part 2 Simple Profile Level 3+ with AAC audio, + encapsulated in MP4 */ +static dlna_profile_t mpeg4_p2_mp4_sp_vga_aac = { + .id = "MPEG4_P2_MP4_SP_VGA_AAC", + .mime = MIME_VIDEO_MPEG_4, + .label = LABEL_VIDEO_SD +}; + +/* Profile for MPEG-4 Part 2 Simple Profile Level 3+ with HEAAC audio, + encapsulated in MP4 */ +static dlna_profile_t mpeg4_p2_mp4_sp_vga_heaac = { + .id = "MPEG4_P2_MP4_SP_VGA_HEAAC", + .mime = MIME_VIDEO_MPEG_4, + .label = LABEL_VIDEO_SD +}; + +/* Profile for MPEG-4 Part 2 Advanced Simple Profile with AAC LC audio, + encapsulated in MP4 */ +static dlna_profile_t mpeg4_p2_mp4_asp_aac = { + .id = "MPEG4_P2_MP4_ASP_AAC", + .mime = MIME_VIDEO_MPEG_4, + .label = LABEL_VIDEO_SD +}; + +/* Profile for MPEG-4 Part 2 Advanced Simple Profile with HEAAC audio, + encapsulated in MP4 */ +static dlna_profile_t mpeg4_p2_mp4_asp_heaac = { + .id = "MPEG4_P2_MP4_ASP_HEAAC", + .mime = MIME_VIDEO_MPEG_4, + .label = LABEL_VIDEO_SD +}; + +/* Profile for MPEG-4 Part 2 Advanced Simple Profile with HEAAC + multi-channel audio, encapsulated in MP4 */ +static dlna_profile_t mpeg4_p2_mp4_asp_heaac_mult5 = { + .id = "MPEG4_P2_MP4_ASP_HEAAC_MULT5", + .mime = MIME_VIDEO_MPEG_4, + .label = LABEL_VIDEO_SD +}; + +/* Profile for MPEG-4 Part 2 Advanced Simple Profile with ATRAC3plus audio, + encapsulated in MP4 */ +static dlna_profile_t mpeg4_p2_mp4_asp_actrac3plus = { + .id = "MPEG4_P2_MP4_ASP_ATRAC3plus", + .mime = MIME_VIDEO_MPEG_4, + .label = LABEL_VIDEO_SD +}; + +/* Profile for MPEG-4 Part 2 Advanced Simple Profile up to Level 5 + with only Simple Object with AAC LC audio, encapsulated in MP4 */ +static dlna_profile_t mpeg4_p2_mp4_asp_l5_so_aac = { + .id = "MPEG4_P2_MP4_ASP_L5_SO_AAC", + .mime = MIME_VIDEO_MPEG_4, + .label = LABEL_VIDEO_SD +}; + +/* Profile for MPEG-4 Part 2 Advanced Simple Profile up to Level 5 + with only Simple Object with HEAAC audio, encapsulated in MP4 */ +static dlna_profile_t mpeg4_p2_mp4_asp_l5_so_heaac = { + .id = "MPEG4_P2_MP4_ASP_L5_SO_HEAAC", + .mime = MIME_VIDEO_MPEG_4, + .label = LABEL_VIDEO_SD +}; + +/* Profile for MPEG-4 Part 2 Advanced Simple Profile up to Level 5 + with only Simple Object with HEAAC multichannel audio, + encapsulated in MP4 */ +static dlna_profile_t mpeg4_p2_mp4_asp_l5_so_heaac_mult5 = { + .id = "MPEG4_P2_MP4_ASP_L5_SO_HEAAC_MULT5", + .mime = MIME_VIDEO_MPEG_4, + .label = LABEL_VIDEO_SD +}; + +/* Profile for MPEG-4 Part 2 Advanced Simple Profile up to Level 4 + with only Simple Object with AAC LC audio, encapsulated in MP4 */ +static dlna_profile_t mpeg4_p2_mp4_asp_l4_so_aac = { + .id = "MPEG4_P2_MP4_ASP_L4_SO_AAC", + .mime = MIME_VIDEO_MPEG_4, + .label = LABEL_VIDEO_CIF30 +}; + +/* Profile for MPEG-4 Part 2 Advanced Simple Profile up to Level 4 + with only Simple Object with HEAAC audio, encapsulated in MP4 */ +static dlna_profile_t mpeg4_p2_mp4_asp_l4_so_heaac = { + .id = "MPEG4_P2_MP4_ASP_L4_SO_HEAAC", + .mime = MIME_VIDEO_MPEG_4, + .label = LABEL_VIDEO_CIF30 +}; + +/* Profile for MPEG-4 Part 2 Advanced Simple Profile up to Level 4 + with only Simple Object with HEAAC multichannel audio, + encapsulated in MP4 */ +static dlna_profile_t mpeg4_p2_mp4_asp_l4_so_heaac_mult5 = { + .id = "MPEG4_P2_MP4_ASP_L4_SO_HEAAC_MULT5", + .mime = MIME_VIDEO_MPEG_4, + .label = LABEL_VIDEO_CIF30 +}; + +/* Profile for H263 Profile 0 Level 10 with AAC LC audio, + encapsulated in MP4 */ +static dlna_profile_t mpeg4_h263_mp4_p0_l10_aac = { + .id = "MPEG4_H263_MP4_P0_L10_AAC", + .mime = MIME_VIDEO_3GP, + .label = LABEL_VIDEO_QCIF15 +}; + +/* Profile for H263 Profile 0 Level 10 with AAC LTP audio, + encapsulated in MP4 */ +static dlna_profile_t mpeg4_h263_mp4_p0_l10_aac_ltp = { + .id = "MPEG4_H263_MP4_P0_L10_AAC_LTP", + .mime = MIME_VIDEO_3GP, + .label = LABEL_VIDEO_QCIF15 +}; + +/*********************/ +/* MPEG-TS Container */ +/*********************/ + +/* Profile for MPEG-4 Part 2 Simple Profile with AAC LC audio, + encapsulated in MPEG2-TS with a zero timestamp field */ +static dlna_profile_t mpeg4_p2_ts_sp_aac = { + .id = "MPEG4_P2_TS_SP_AAC", + .mime = MIME_VIDEO_MPEG_TS, + .label = LABEL_VIDEO_CIF30 +}; + +/* Profile for MPEG-4 Part 2 Simple Profile with AAC LC audio, + encapsulated in MPEG2-TS with a valid timestamp field */ +static dlna_profile_t mpeg4_p2_ts_sp_aac_t = { + .id = "MPEG4_P2_TS_SP_AAC_T", + .mime = MIME_VIDEO_MPEG_TS, + .label = LABEL_VIDEO_CIF30 +}; + +/* Profile for MPEG-4 Part 2 Simple Profile with AAC LC audio, + encapsulated in MPEG2-TS without a timestamp field */ +static dlna_profile_t mpeg4_p2_ts_sp_aac_iso = { + .id = "MPEG4_P2_TS_SP_AAC_ISO", + .mime = MIME_VIDEO_MPEG, + .label = LABEL_VIDEO_CIF30 +}; + +/* Profile for MPEG-4 Part 2 Simple Profile with MPEG-1 Layer3 audio, + encapsulated in MPEG2-TS with a zero timestamp field */ +static dlna_profile_t mpeg4_p2_ts_sp_mpeg1_l3 = { + .id = "MPEG4_P2_TS_SP_MPEG1_L3", + .mime = MIME_VIDEO_MPEG_TS, + .label = LABEL_VIDEO_CIF30 +}; + +/* Profile for MPEG-4 Part 2 Simple Profile with MPEG-1 Layer3 audio, + encapsulated in MPEG2-TS with a valid timestamp field */ +static dlna_profile_t mpeg4_p2_ts_sp_mpeg1_l3_t = { + .id = "MPEG4_P2_TS_SP_MPEG1_L3_T", + .mime = MIME_VIDEO_MPEG_TS, + .label = LABEL_VIDEO_CIF30 +}; + +/* Profile for MPEG-4 Part 2 Simple Profile with MPEG-1 Layer3 audio, + encapsulated in MPEG2-TS without a timestamp field */ +static dlna_profile_t mpeg4_p2_ts_sp_mpeg1_l3_iso = { + .id = "MPEG4_P2_TS_SP_MPEG1_L3_ISO", + .mime = MIME_VIDEO_MPEG, + .label = LABEL_VIDEO_CIF30 +}; + +/* Profile for MPEG-4 Part 2 Simple Profile with AC3 multichannel audio, + encapsulated in MPEG2-TS with a zero timestamp field */ +static dlna_profile_t mpeg4_p2_ts_sp_ac3 = { + .id = "MPEG4_P2_TS_SP_AC3_L3", + .mime = MIME_VIDEO_MPEG_TS, + .label = LABEL_VIDEO_CIF30 +}; + +/* Profile for MPEG-4 Part 2 Simple Profile with AC3 multichannel audio, + encapsulated in MPEG2-TS with a valid timestamp field */ +static dlna_profile_t mpeg4_p2_ts_sp_ac3_t = { + .id = "MPEG4_P2_TS_SP_AC3_T", + .mime = MIME_VIDEO_MPEG_TS, + .label = LABEL_VIDEO_CIF30 +}; + +/* Profile for MPEG-4 Part 2 Simple Profile with AC3 multichannel audio, + encapsulated in MPEG2-TS without a timestamp field */ +static dlna_profile_t mpeg4_p2_ts_sp_ac3_iso = { + .id = "MPEG4_P2_TS_SP_AC3_ISO", + .mime = MIME_VIDEO_MPEG, + .label = LABEL_VIDEO_CIF30 +}; + +/* Profile for MPEG-4 Part 2 Simple Profile with MPEG-1/2 Layer 1/2 + multichannel audio, encapsulated in MPEG2-TS with a zero timestamp field */ +static dlna_profile_t mpeg4_p2_ts_sp_mpeg2_l2 = { + .id = "MPEG4_P2_TS_SP_MPEG2_L2", + .mime = MIME_VIDEO_MPEG_TS, + .label = LABEL_VIDEO_CIF30 +}; + +/* Profile for MPEG-4 Part 2 Simple Profile with MPEG-1/2 Layer1/2 + multichannel audio, + encapsulated in MPEG2-TS with a valid timestamp field */ +static dlna_profile_t mpeg4_p2_ts_sp_mpeg2_l2_t = { + .id = "MPEG4_P2_TS_SP_MPEG2_L2_T", + .mime = MIME_VIDEO_MPEG_TS, + .label = LABEL_VIDEO_CIF30 +}; + +/* Profile for MPEG-4 Part 2 Simple Profile with MPEG-1/2 Layer1/2 + multichannel audio, + encapsulated in MPEG2-TS without a timestamp field */ +static dlna_profile_t mpeg4_p2_ts_sp_mpeg2_l2_iso = { + .id = "MPEG4_P2_TS_SP_MPEG2_L2_ISO", + .mime = MIME_VIDEO_MPEG, + .label = LABEL_VIDEO_CIF30 +}; + +/* Profile for MPEG-4 Part 2 Advanced Simple Profile with AAC LC audio, + encapsulated in MPEG2-TS with a zero timestamp field */ +static dlna_profile_t mpeg4_p2_ts_asp_aac = { + .id = "MPEG4_P2_TS_ASP_AAC", + .mime = MIME_VIDEO_MPEG_TS, + .label = LABEL_VIDEO_SD +}; + +/* Profile for MPEG-4 Part 2 Advanced Simple Profile with AAC LC audio, + encapsulated in MPEG2-TS with a valid timestamp field */ +static dlna_profile_t mpeg4_p2_ts_asp_aac_t = { + .id = "MPEG4_P2_TS_ASP_AAC_T", + .mime = MIME_VIDEO_MPEG_TS, + .label = LABEL_VIDEO_CIF30 +}; + +/* Profile for MPEG-4 Part 2 Advanced Simple Profile with AAC LC audio, + encapsulated in MPEG2-TS without a timestamp field */ +static dlna_profile_t mpeg4_p2_ts_asp_aac_iso = { + .id = "MPEG4_P2_TS_ASP_AAC_ISO", + .mime = MIME_VIDEO_MPEG, + .label = LABEL_VIDEO_SD +}; + +/* Profile for MPEG-4 Part 2 Advanced Simple Profile with MPEG-1 Layer3 audio, + encapsulated in MPEG2-TS with a zero timestamp field */ +static dlna_profile_t mpeg4_p2_ts_asp_mpeg1_l3 = { + .id = "MPEG4_P2_TS_ASP_MPEG1_L3", + .mime = MIME_VIDEO_MPEG_TS, + .label = LABEL_VIDEO_SD +}; + +/* Profile for MPEG-4 Part 2 Advanced Simple Profile with MPEG-1 Layer3 audio, + encapsulated in MPEG2-TS with a valid timestamp field */ +static dlna_profile_t mpeg4_p2_ts_asp_mpeg1_l3_t = { + .id = "MPEG4_P2_TS_ASP_MPEG1_L3_T", + .mime = MIME_VIDEO_MPEG_TS, + .label = LABEL_VIDEO_SD +}; + +/* Profile for MPEG-4 Part 2 Advanced Simple Profile with MPEG-1 Layer3 audio, + encapsulated in MPEG2-TS without a timestamp field */ +static dlna_profile_t mpeg4_p2_ts_asp_mpeg1_l3_iso = { + .id = "MPEG4_P2_TS_ASP_MPEG1_L3_ISO", + .mime = MIME_VIDEO_MPEG, + .label = LABEL_VIDEO_SD +}; + +/* Profile for MPEG-4 Part 2 Advanced Simple Profile with AC3 + multichannel audio, + encapsulated in MPEG2-TS with a zero timestamp field */ +static dlna_profile_t mpeg4_p2_ts_asp_ac3 = { + .id = "MPEG4_P2_TS_ASP_AC3_L3", + .mime = MIME_VIDEO_MPEG_TS, + .label = LABEL_VIDEO_SD +}; + +/* Profile for MPEG-4 Part 2 Advanced Simple Profile with AC3 + multichannel audio, + encapsulated in MPEG2-TS with a valid timestamp field */ +static dlna_profile_t mpeg4_p2_ts_asp_ac3_t = { + .id = "MPEG4_P2_TS_ASP_AC3_T", + .mime = MIME_VIDEO_MPEG_TS, + .label = LABEL_VIDEO_SD +}; + +/* Profile for MPEG-4 Part 2 Advanced Simple Profile with AC3 + multichannel audio, + encapsulated in MPEG2-TS without a timestamp field */ +static dlna_profile_t mpeg4_p2_ts_asp_ac3_iso = { + .id = "MPEG4_P2_TS_ASP_AC3_ISO", + .mime = MIME_VIDEO_MPEG, + .label = LABEL_VIDEO_SD +}; + +/* Profile for MPEG-4 Part 2 Core Profile with AC3 multichannel audio, + encapsulated in MPEG2-TS with a zero timestamp field */ +static dlna_profile_t mpeg4_p2_ts_co_ac3 = { + .id = "MPEG4_P2_TS_CO_AC3", + .mime = MIME_VIDEO_MPEG_TS, + .label = LABEL_VIDEO_CIF30 +}; + +/* Profile for MPEG-4 Part 2 Core Profile with AC3 multichannel audio, + encapsulated in MPEG2-TS with a valid timestamp field */ +static dlna_profile_t mpeg4_p2_ts_co_ac3_t = { + .id = "MPEG4_P2_TS_CO_AC3_T", + .mime = MIME_VIDEO_MPEG_TS, + .label = LABEL_VIDEO_CIF30 +}; + +/* Profile for MPEG-4 Part 2 Core Profile with AC3 multichannel audio, + encapsulated in MPEG2-TS without a timestamp field */ +static dlna_profile_t mpeg4_p2_ts_co_ac3_iso = { + .id = "MPEG4_P2_TS_CO_AC3_ISO", + .mime = MIME_VIDEO_MPEG, + .label = LABEL_VIDEO_CIF30 +}; + +/* Profile for MPEG-4 Part 2 Core Profile with MPEG-1/2 Layer1/2 audio, + encapsulated in MPEG2-TS with a zero timestamp field */ +static dlna_profile_t mpeg4_p2_ts_co_mpeg2_l2 = { + .id = "MPEG4_P2_TS_CO_MPEG2_L2", + .mime = MIME_VIDEO_MPEG_TS, + .label = LABEL_VIDEO_CIF30 +}; + +/* Profile for MPEG-4 Part 2 Core Profile with MPEG-1/2 Layer1/2 audio, + encapsulated in MPEG2-TS with a valid timestamp field */ +static dlna_profile_t mpeg4_p2_ts_co_mpeg2_l2_t = { + .id = "MPEG4_P2_TS_CO_MPEG2_L2_T", + .mime = MIME_VIDEO_MPEG_TS, + .label = LABEL_VIDEO_CIF30 +}; + +/* Profile for MPEG-4 Part 2 Core Profile with MPEG-1/2 Layer1/2 audio, + encapsulated in MPEG2-TS without a timestamp field */ +static dlna_profile_t mpeg4_p2_ts_co_mpeg2_l2_iso = { + .id = "MPEG4_P2_TS_CO_MPEG2_L2_ISO", + .mime = MIME_VIDEO_MPEG, + .label = LABEL_VIDEO_CIF30 +}; + +/*****************/ +/* ASF Container */ +/*****************/ + +/* Profile for MPEG-4 Part 2 Simple Profile with G.726 audio, + encapsulated in ASF */ +static dlna_profile_t mpeg4_p2_asf_sp_g726 = { + .id = "MPEG4_P2_ASF_SP_G726", + .mime = MIME_VIDEO_ASF, + .label = LABEL_VIDEO_CIF30 +}; + +/* Profile for MPEG-4 Part 2 Advanced Simple Profile up to Level 5 + with only Simple Object with G.726 audio, encapsulated in ASF */ +static dlna_profile_t mpeg4_p2_asf_asp_l5_so_g726 = { + .id = "MPEG4_P2_ASF_ASP_L5_SO_G726", + .mime = MIME_VIDEO_ASF, + .label = LABEL_VIDEO_SD +}; + +/* Profile for MPEG-4 Part 2 Advanced Simple Profile up to Level 4 + with only Simple Object with G.726 audio, encapsulated in ASF */ +static dlna_profile_t mpeg4_p2_asf_asp_l4_so_g726 = { + .id = "MPEG4_P2_ASF_ASP_L4_SO_G726", + .mime = MIME_VIDEO_ASF, + .label = LABEL_VIDEO_CIF30 +}; + +/******************/ +/* 3GPP Container */ +/******************/ + +/* Profile for H.263 Profile 0 Level 10 with AMR-WB+ audio, + encapsulated in 3GPP */ +static dlna_profile_t mpeg4_h263_3gpp_p0_l10_amr_wbplus = { + .id = "MPEG4_H263_3GPP_P0_L10_AMR_WBplus", + .mime = MIME_VIDEO_3GP, + .label = LABEL_VIDEO_QCIF15 +}; + +/* Profile for MPEG-4 Part 2 Simple Profile Level 0b with AAC audio, + encapsulated in 3GPP */ +static dlna_profile_t mpeg4_p2_3gpp_sp_l0b_aac = { + .id = "MPEG4_P2_3GPP_SP_L0B_AAC", + .mime = MIME_VIDEO_3GP, + .label = LABEL_VIDEO_QCIF15 +}; + +/* Profile for MPEG-4 Part 2 Simple Profile Level 0b with AMR audio, + encapsulated in 3GPP */ +static dlna_profile_t mpeg4_p2_3gpp_sp_l0b_amr = { + .id = "MPEG4_P2_3GPP_SP_L0B_AMR", + .mime = MIME_VIDEO_3GP, + .label = LABEL_VIDEO_QCIF15 +}; + +/* Profile for MPEG-4 H.263 Profile 3 Level 10 with AMR audio, + encapsulated in 3GPP */ +static dlna_profile_t mpeg4_h263_3gpp_p3_l10_amr = { + .id = "MPEG4_H263_3GPP_P3_L10_AMR", + .mime = MIME_VIDEO_3GP, + .label = LABEL_VIDEO_QCIF15 +}; + +static const struct { + dlna_profile_t *profile; + dlna_container_type_t st; + mpeg4_video_profile_t vp; + audio_profile_t ap; +} mpeg4_profiles_mapping[] = { + /* MPEG-4 Container */ + { &mpeg4_p2_mp4_sp_aac, CT_MP4, + MPEG4_VIDEO_PROFILE_P2_SP_L3, AUDIO_PROFILE_AAC }, + { &mpeg4_p2_mp4_sp_heaac, CT_MP4, + MPEG4_VIDEO_PROFILE_P2_SP_L3, AUDIO_PROFILE_AAC_HE_L2 }, + { &mpeg4_p2_mp4_sp_atrac3plus, CT_MP4, + MPEG4_VIDEO_PROFILE_P2_SP_L3, AUDIO_PROFILE_ATRAC }, + { &mpeg4_p2_mp4_sp_aac_ltp, CT_MP4, + MPEG4_VIDEO_PROFILE_P2_SP_L3, AUDIO_PROFILE_AAC_LTP }, + + { &mpeg4_p2_mp4_sp_l2_aac, CT_MP4, + MPEG4_VIDEO_PROFILE_P2_SP_L2, AUDIO_PROFILE_AAC }, + { &mpeg4_p2_mp4_sp_l2_amr, CT_MP4, + MPEG4_VIDEO_PROFILE_P2_SP_L2, AUDIO_PROFILE_AMR }, + + { &mpeg4_p2_mp4_sp_vga_aac, CT_MP4, + MPEG4_VIDEO_PROFILE_P2_SP_L3_VGA, AUDIO_PROFILE_AAC }, + { &mpeg4_p2_mp4_sp_vga_heaac, CT_MP4, + MPEG4_VIDEO_PROFILE_P2_SP_L3_VGA, AUDIO_PROFILE_AAC_HE_L2 }, + + { &mpeg4_p2_mp4_asp_aac, CT_MP4, + MPEG4_VIDEO_PROFILE_P2_ASP_L5, AUDIO_PROFILE_AAC }, + { &mpeg4_p2_mp4_asp_heaac, CT_MP4, + MPEG4_VIDEO_PROFILE_P2_ASP_L5, AUDIO_PROFILE_AAC_HE_L2 }, + { &mpeg4_p2_mp4_asp_heaac_mult5, CT_MP4, + MPEG4_VIDEO_PROFILE_P2_ASP_L5, AUDIO_PROFILE_AAC_HE_MULT5 }, + { &mpeg4_p2_mp4_asp_actrac3plus, CT_MP4, + MPEG4_VIDEO_PROFILE_P2_ASP_L5, AUDIO_PROFILE_ATRAC }, + + { &mpeg4_p2_mp4_asp_l5_so_aac, CT_MP4, + MPEG4_VIDEO_PROFILE_P2_ASP_L5, AUDIO_PROFILE_AAC }, + { &mpeg4_p2_mp4_asp_l5_so_heaac, CT_MP4, + MPEG4_VIDEO_PROFILE_P2_ASP_L5, AUDIO_PROFILE_AAC_HE_L2 }, + { &mpeg4_p2_mp4_asp_l5_so_heaac_mult5, CT_MP4, + MPEG4_VIDEO_PROFILE_P2_ASP_L5, AUDIO_PROFILE_AAC_HE_MULT5 }, + + { &mpeg4_p2_mp4_asp_l4_so_aac, CT_MP4, + MPEG4_VIDEO_PROFILE_P2_ASP_L4, AUDIO_PROFILE_AAC }, + { &mpeg4_p2_mp4_asp_l4_so_heaac, CT_MP4, + MPEG4_VIDEO_PROFILE_P2_ASP_L4, AUDIO_PROFILE_AAC_HE_L2 }, + { &mpeg4_p2_mp4_asp_l4_so_heaac_mult5, CT_MP4, + MPEG4_VIDEO_PROFILE_P2_ASP_L4, AUDIO_PROFILE_AAC_HE_MULT5 }, + + { &mpeg4_h263_mp4_p0_l10_aac, CT_MP4, + MPEG4_VIDEO_PROFILE_H263, AUDIO_PROFILE_AAC }, + { &mpeg4_h263_mp4_p0_l10_aac_ltp, CT_MP4, + MPEG4_VIDEO_PROFILE_H263, AUDIO_PROFILE_AAC_LTP }, + + /* MPEG-TS Container */ + { &mpeg4_p2_ts_sp_aac, CT_MPEG_TRANSPORT_STREAM_DLNA_NO_TS, + MPEG4_VIDEO_PROFILE_P2_SP_L3, AUDIO_PROFILE_AAC }, + { &mpeg4_p2_ts_sp_aac_t, CT_MPEG_TRANSPORT_STREAM_DLNA, + MPEG4_VIDEO_PROFILE_P2_SP_L3, AUDIO_PROFILE_AAC }, + { &mpeg4_p2_ts_sp_aac_iso, CT_MPEG_TRANSPORT_STREAM, + MPEG4_VIDEO_PROFILE_P2_SP_L3, AUDIO_PROFILE_AAC }, + + { &mpeg4_p2_ts_sp_mpeg1_l3, CT_MPEG_TRANSPORT_STREAM_DLNA_NO_TS, + MPEG4_VIDEO_PROFILE_P2_SP_L3, AUDIO_PROFILE_MP3 }, + { &mpeg4_p2_ts_sp_mpeg1_l3_t, CT_MPEG_TRANSPORT_STREAM_DLNA, + MPEG4_VIDEO_PROFILE_P2_SP_L3, AUDIO_PROFILE_MP3 }, + { &mpeg4_p2_ts_sp_mpeg1_l3_iso, CT_MPEG_TRANSPORT_STREAM, + MPEG4_VIDEO_PROFILE_P2_SP_L3, AUDIO_PROFILE_MP3 }, + + { &mpeg4_p2_ts_sp_ac3, CT_MPEG_TRANSPORT_STREAM_DLNA_NO_TS, + MPEG4_VIDEO_PROFILE_P2_SP_L3, AUDIO_PROFILE_AC3 }, + { &mpeg4_p2_ts_sp_ac3_t, CT_MPEG_TRANSPORT_STREAM_DLNA, + MPEG4_VIDEO_PROFILE_P2_SP_L3, AUDIO_PROFILE_AC3 }, + { &mpeg4_p2_ts_sp_ac3_iso, CT_MPEG_TRANSPORT_STREAM, + MPEG4_VIDEO_PROFILE_P2_SP_L3, AUDIO_PROFILE_AC3 }, + + { &mpeg4_p2_ts_sp_mpeg2_l2, CT_MPEG_TRANSPORT_STREAM_DLNA_NO_TS, + MPEG4_VIDEO_PROFILE_P2_SP_L3, AUDIO_PROFILE_MP2 }, + { &mpeg4_p2_ts_sp_mpeg2_l2_t, CT_MPEG_TRANSPORT_STREAM_DLNA, + MPEG4_VIDEO_PROFILE_P2_SP_L3, AUDIO_PROFILE_MP2 }, + { &mpeg4_p2_ts_sp_mpeg2_l2_iso, CT_MPEG_TRANSPORT_STREAM, + MPEG4_VIDEO_PROFILE_P2_SP_L3, AUDIO_PROFILE_MP2 }, + + { &mpeg4_p2_ts_asp_aac, CT_MPEG_TRANSPORT_STREAM_DLNA_NO_TS, + MPEG4_VIDEO_PROFILE_P2_ASP_L5, AUDIO_PROFILE_AAC }, + { &mpeg4_p2_ts_asp_aac_t, CT_MPEG_TRANSPORT_STREAM_DLNA, + MPEG4_VIDEO_PROFILE_P2_ASP_L5, AUDIO_PROFILE_AAC }, + { &mpeg4_p2_ts_asp_aac_iso, CT_MPEG_TRANSPORT_STREAM, + MPEG4_VIDEO_PROFILE_P2_ASP_L5, AUDIO_PROFILE_AAC }, + + { &mpeg4_p2_ts_asp_mpeg1_l3, CT_MPEG_TRANSPORT_STREAM_DLNA_NO_TS, + MPEG4_VIDEO_PROFILE_P2_ASP_L5, AUDIO_PROFILE_MP3 }, + { &mpeg4_p2_ts_asp_mpeg1_l3_t, CT_MPEG_TRANSPORT_STREAM_DLNA, + MPEG4_VIDEO_PROFILE_P2_ASP_L5, AUDIO_PROFILE_MP3 }, + { &mpeg4_p2_ts_asp_mpeg1_l3_iso, CT_MPEG_TRANSPORT_STREAM, + MPEG4_VIDEO_PROFILE_P2_ASP_L5, AUDIO_PROFILE_MP3 }, + + { &mpeg4_p2_ts_asp_ac3, CT_MPEG_TRANSPORT_STREAM_DLNA_NO_TS, + MPEG4_VIDEO_PROFILE_P2_ASP_L5, AUDIO_PROFILE_AC3 }, + { &mpeg4_p2_ts_asp_ac3_t, CT_MPEG_TRANSPORT_STREAM_DLNA, + MPEG4_VIDEO_PROFILE_P2_ASP_L5, AUDIO_PROFILE_AC3 }, + { &mpeg4_p2_ts_asp_ac3_iso, CT_MPEG_TRANSPORT_STREAM, + MPEG4_VIDEO_PROFILE_P2_ASP_L5, AUDIO_PROFILE_AC3 }, + + { &mpeg4_p2_ts_co_ac3, CT_MPEG_TRANSPORT_STREAM_DLNA_NO_TS, + MPEG4_VIDEO_PROFILE_P2_ASP_L4, AUDIO_PROFILE_AC3 }, + { &mpeg4_p2_ts_co_ac3_t, CT_MPEG_TRANSPORT_STREAM_DLNA, + MPEG4_VIDEO_PROFILE_P2_ASP_L4, AUDIO_PROFILE_AC3 }, + { &mpeg4_p2_ts_co_ac3_iso, CT_MPEG_TRANSPORT_STREAM, + MPEG4_VIDEO_PROFILE_P2_ASP_L4, AUDIO_PROFILE_AC3 }, + + { &mpeg4_p2_ts_co_mpeg2_l2, CT_MPEG_TRANSPORT_STREAM_DLNA_NO_TS, + MPEG4_VIDEO_PROFILE_P2_ASP_L4, AUDIO_PROFILE_MP2 }, + { &mpeg4_p2_ts_co_mpeg2_l2_t, CT_MPEG_TRANSPORT_STREAM_DLNA, + MPEG4_VIDEO_PROFILE_P2_ASP_L4, AUDIO_PROFILE_MP2 }, + { &mpeg4_p2_ts_co_mpeg2_l2_iso, CT_MPEG_TRANSPORT_STREAM, + MPEG4_VIDEO_PROFILE_P2_ASP_L4, AUDIO_PROFILE_MP2 }, + + /* ASF Container */ + { &mpeg4_p2_asf_sp_g726, CT_ASF, + MPEG4_VIDEO_PROFILE_P2_SP_L3, AUDIO_PROFILE_G726 }, + { &mpeg4_p2_asf_asp_l5_so_g726, CT_ASF, + MPEG4_VIDEO_PROFILE_P2_ASP_L5, AUDIO_PROFILE_G726 }, + { &mpeg4_p2_asf_asp_l4_so_g726, CT_ASF, + MPEG4_VIDEO_PROFILE_P2_ASP_L4, AUDIO_PROFILE_G726 }, + + /* 3GPP Container */ + { &mpeg4_h263_3gpp_p0_l10_amr_wbplus, CT_3GP, + MPEG4_VIDEO_PROFILE_H263, AUDIO_PROFILE_AMR_WB }, + { &mpeg4_p2_3gpp_sp_l0b_aac, CT_3GP, + MPEG4_VIDEO_PROFILE_P2_SP_L0B, AUDIO_PROFILE_AAC }, + { &mpeg4_p2_3gpp_sp_l0b_amr, CT_3GP, + MPEG4_VIDEO_PROFILE_P2_SP_L0B, AUDIO_PROFILE_AMR }, + { &mpeg4_h263_3gpp_p3_l10_amr, CT_3GP, + MPEG4_VIDEO_PROFILE_H263, AUDIO_PROFILE_AMR }, + + { NULL, 0, 0, 0 } +}; + +static mpeg4_vcodec_type_t +mpeg4_get_vcodec (AVCodecContext *vc) +{ + int i; + + if (!vc) + return MPEG4_VCODEC_INVALID; + + for (i = 0; avf_vcodec_mapping[i].codec_id != -1; i++) + if (vc->codec_id == (unsigned int) avf_vcodec_mapping[i].codec_id) + return avf_vcodec_mapping[i].type; + + return MPEG4_VCODEC_INVALID; +} + +static inline int +is_valid_video_profile (video_properties_t res[], int size, + AVStream *vs, AVCodecContext *vc) +{ + int i; + + for (i = 0; i < size / (int) sizeof (video_properties_t); i++) + { + if (res[i].width == vc->width && + res[i].height == vc->height && + (vs->r_frame_rate.num / vs->r_frame_rate.num) + <= (res[i].fps_num / res[i].fps_den)) + return 1; + } + + return 0; +} + +static mpeg4_video_profile_t +mpeg4_video_get_profile (mpeg4_vcodec_type_t vctype, + AVStream *vs, AVCodecContext *vc) +{ + if (!vs || !vc) + return MPEG4_VIDEO_PROFILE_INVALID; + + if (vctype == MPEG4_VCODEC_H263) + { + if (vc->bit_rate > 64000) /* max bitrate is 64 kbps */ + return MPEG4_VIDEO_PROFILE_INVALID; + + if (is_valid_video_profile (profile_h263_res, + sizeof (profile_h263_res), vs, vc)) + return MPEG4_VIDEO_PROFILE_H263; + + return MPEG4_VIDEO_PROFILE_INVALID; + } + else if (vctype == MPEG4_VCODEC_P2) + { + if (vc->bit_rate <= 128000) /* SP_L2 and SP_L0B */ + { + if (is_valid_video_profile (profile_p2_sp_l0b_res, + sizeof (profile_p2_sp_l0b_res), vs, vc)) + return MPEG4_VIDEO_PROFILE_P2_SP_L0B; + + if (is_valid_video_profile (profile_p2_sp_l2_res, + sizeof (profile_p2_sp_l2_res), vs, vc)) + return MPEG4_VIDEO_PROFILE_P2_SP_L2; + + return MPEG4_VIDEO_PROFILE_INVALID; + } + else if (vc->bit_rate <= 384000) /* SP_L3 */ + { + if (is_valid_video_profile (profile_p2_sp_l3_co_res, + sizeof (profile_p2_sp_l3_co_res), vs, vc)) + return MPEG4_VIDEO_PROFILE_P2_SP_L3; + + return MPEG4_VIDEO_PROFILE_INVALID; + } + else if (vc->bit_rate <= 2000000) /* CO and ASP_L4 */ + { + if (is_valid_video_profile (profile_p2_sp_l3_co_res, + sizeof (profile_p2_sp_l3_co_res), vs, vc)) + return MPEG4_VIDEO_PROFILE_P2_ASP_L4; + + if (is_valid_video_profile (profile_p2_asp_l4_res, + sizeof (profile_p2_asp_l4_res), vs, vc)) + return MPEG4_VIDEO_PROFILE_P2_ASP_L4; + + return MPEG4_VIDEO_PROFILE_INVALID; + } + else if (vc->bit_rate <= 3000000) /* SP_L3_VGA */ + { + if (is_valid_video_profile (profile_p2_sp_l3_vga_res, + sizeof (profile_p2_sp_l3_vga_res), vs, vc)) + return MPEG4_VIDEO_PROFILE_P2_SP_L3_VGA; + + return MPEG4_VIDEO_PROFILE_INVALID; + } + else if (vc->bit_rate <= 8000000) /* ASP_L5 */ + { + if (is_valid_video_profile (profile_p2_asp_l5_res, + sizeof (profile_p2_asp_l5_res), vs, vc)) + return MPEG4_VIDEO_PROFILE_P2_ASP_L5; + + return MPEG4_VIDEO_PROFILE_INVALID; + } + + return MPEG4_VIDEO_PROFILE_INVALID; + } + + return MPEG4_VIDEO_PROFILE_INVALID; +} + +static dlna_profile_t * +probe_mpeg4_part2 (AVFormatContext *ctx, + dlna_container_type_t st, + av_codecs_t *codecs) +{ + mpeg4_vcodec_type_t vctype; + mpeg4_video_profile_t vp; + audio_profile_t ap; + int i; + + if (!stream_ctx_is_av (codecs)) + return NULL; + + vctype = mpeg4_get_vcodec (codecs->vc); + if (vctype == MPEG4_VCODEC_INVALID) + return NULL; + + /* check for a supported container */ + if (st != CT_ASF && + st != CT_3GP && + st != CT_MP4 && + st != CT_MPEG_TRANSPORT_STREAM && + st != CT_MPEG_TRANSPORT_STREAM_DLNA && + st != CT_MPEG_TRANSPORT_STREAM_DLNA_NO_TS) + return NULL; + + /* ensure we have a valid video codec bit rate */ + if (codecs->vc->bit_rate == 0) + codecs->vc->bit_rate = codecs->ac->bit_rate ? + ctx->bit_rate - codecs->ac->bit_rate : ctx->bit_rate; + + /* check for valid video profile */ + vp = mpeg4_video_get_profile (vctype, codecs->vs, codecs->vc); + if (vp == MPEG4_VIDEO_PROFILE_INVALID) + return NULL; + + /* check for valid audio profile */ + ap = audio_profile_guess (codecs->ac); + if (ap == AUDIO_PROFILE_INVALID) + return NULL; + + /* AAC fixup: _320 profiles are audio-only profiles */ + if (ap == AUDIO_PROFILE_AAC_320) + ap = AUDIO_PROFILE_AAC; + if (ap == AUDIO_PROFILE_AAC_HE_L2_320) + ap = AUDIO_PROFILE_AAC_HE_L2; + + /* find profile according to container type, video and audio profiles */ + for (i = 0; mpeg4_profiles_mapping[i].profile; i++) + if (mpeg4_profiles_mapping[i].st == st && + mpeg4_profiles_mapping[i].vp == vp && + mpeg4_profiles_mapping[i].ap == ap) + return mpeg4_profiles_mapping[i].profile; + + return NULL; +} + +dlna_registered_profile_t dlna_profile_av_mpeg4_part2 = { + .id = DLNA_PROFILE_AV_MPEG4_PART2, + .class = DLNA_CLASS_AV, + .extensions = "mov,hdmov,mp4,3gp,3gpp,asf,mpg,mpeg,mpe,mp2t,ts", + .probe = probe_mpeg4_part2, + .next = NULL +};