comparison libdlna-0.2.3/src/containers.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
comparison
equal deleted inserted replaced
128:3a7d8d2f0585 129:4f6d9621ee00
1 #include <string.h>
2 #include <unistd.h>
3 #include <sys/types.h>
4 #include <sys/stat.h>
5 #include <fcntl.h>
6
7 #include <ffmpeg/avformat.h>
8
9 #include "containers.h"
10 #include "profiles.h"
11
12 #define MPEG_PACK_HEADER 0xba
13 #define MPEG_TS_SYNC_CODE 0x47
14 #define MPEG_TS_PACKET_LENGTH 188
15 #define MPEG_TS_PACKET_LENGTH_DLNA 192 /* prepends 4 bytes to TS packet */
16
17 static const struct {
18 const char *name;
19 const dlna_container_type_t type;
20 } avf_format_mapping[] = {
21 { "image2", CT_IMAGE },
22 { "asf", CT_ASF },
23 { "amr", CT_AMR },
24 { "aac", CT_AAC },
25 { "ac3", CT_AC3 },
26 { "mp3", CT_MP3 },
27 { "wav", CT_WAV },
28 { "mov,mp4,m4a,3gp,3g2,mj2", CT_MOV },
29 { "mpeg", CT_FF_MPEG },
30 { "mpegts", CT_FF_MPEG_TS },
31 { NULL, 0 }
32 };
33
34 static dlna_container_type_t
35 mpeg_find_container_type (const char *filename)
36 {
37 unsigned char buffer[2*MPEG_TS_PACKET_LENGTH_DLNA+1];
38 int fd, i;
39
40 /* read file header */
41 fd = open (filename, O_RDONLY);
42 read (fd, buffer, 2 * MPEG_TS_PACKET_LENGTH_DLNA);
43 close (fd);
44
45 /* check for MPEG-TS container */
46 for (i = 0; i < MPEG_TS_PACKET_LENGTH; i++)
47 {
48 if (buffer[i] == MPEG_TS_SYNC_CODE)
49 {
50 if (buffer[i + MPEG_TS_PACKET_LENGTH] == MPEG_TS_SYNC_CODE)
51 return CT_MPEG_TRANSPORT_STREAM;
52 }
53 }
54
55 /* check for DLNA specific MPEG-TS container */
56 for (i = 0; i < MPEG_TS_PACKET_LENGTH_DLNA; i++)
57 {
58 if (buffer[i] == MPEG_TS_SYNC_CODE)
59 {
60 if (buffer[i + MPEG_TS_PACKET_LENGTH_DLNA] == MPEG_TS_SYNC_CODE)
61 {
62 if (buffer[i] == 0x00 && buffer [i+1] == 0x00 &&
63 buffer [i+2] == 0x00 && buffer [i+3] == 0x00)
64 return CT_MPEG_TRANSPORT_STREAM_DLNA_NO_TS; /* empty timestamp */
65 else
66 return CT_MPEG_TRANSPORT_STREAM_DLNA; /* valid timestamp */
67 }
68 }
69 }
70
71 /* check for MPEG-PS and MPEG-(P)ES container */
72 if (buffer[0] == 0x00 && buffer[1] == 0x00 && buffer[2] == 0x01)
73 return (buffer[3] == MPEG_PACK_HEADER) ?
74 CT_MPEG_PROGRAM_STREAM : CT_MPEG_ELEMENTARY_STREAM;
75
76 return CT_UNKNOWN;
77 }
78
79 static dlna_container_type_t
80 mov_find_container_type (const char *filename)
81 {
82 if (!filename)
83 return CT_UNKNOWN;
84
85 if (!strcasecmp (get_file_extension (filename), "3gp") ||
86 !strcasecmp (get_file_extension (filename), "3gpp") ||
87 !strcasecmp (get_file_extension (filename), "3g2"))
88 return CT_3GP;
89
90 return CT_MP4;
91 }
92
93 dlna_container_type_t
94 stream_get_container (AVFormatContext *ctx)
95 {
96 int i;
97
98 #ifdef HAVE_DEBUG
99 fprintf (stderr, "Found container: %s\n", ctx->iformat->name);
100 #endif /* HAVE_DEBUG */
101
102 for (i = 0; avf_format_mapping[i].name; i++)
103 if (!strcmp (ctx->iformat->name, avf_format_mapping[i].name))
104 {
105 switch (avf_format_mapping[i].type)
106 {
107 case CT_FF_MPEG:
108 case CT_FF_MPEG_TS:
109 return mpeg_find_container_type (ctx->filename);
110 case CT_MOV:
111 return mov_find_container_type (ctx->filename);
112 default:
113 return avf_format_mapping[i].type;
114 }
115 }
116
117 /* unknown or invalid container */
118 return CT_UNKNOWN;
119 }