Originally committed as revision 11635 to svn://svn.ffmpeg.org/ffmpeg/trunk
Evgeniy Stepanov authored on 2008/01/28 00:43:17... | ... |
@@ -2776,6 +2776,7 @@ static void opt_input_file(const char *filename) |
2776 | 2776 |
if(subtitle_disable) |
2777 | 2777 |
ic->streams[i]->discard = AVDISCARD_ALL; |
2778 | 2778 |
break; |
2779 |
+ case CODEC_TYPE_ATTACHMENT: |
|
2779 | 2780 |
case CODEC_TYPE_UNKNOWN: |
2780 | 2781 |
break; |
2781 | 2782 |
default: |
... | ... |
@@ -2825,6 +2826,7 @@ static void check_audio_video_sub_inputs(int *has_video_ptr, int *has_audio_ptr, |
2825 | 2825 |
has_subtitle = 1; |
2826 | 2826 |
break; |
2827 | 2827 |
case CODEC_TYPE_DATA: |
2828 |
+ case CODEC_TYPE_ATTACHMENT: |
|
2828 | 2829 |
case CODEC_TYPE_UNKNOWN: |
2829 | 2830 |
break; |
2830 | 2831 |
default: |
... | ... |
@@ -33,8 +33,8 @@ |
33 | 33 |
#define AV_STRINGIFY(s) AV_TOSTRING(s) |
34 | 34 |
#define AV_TOSTRING(s) #s |
35 | 35 |
|
36 |
-#define LIBAVCODEC_VERSION_INT ((51<<16)+(49<<8)+0) |
|
37 |
-#define LIBAVCODEC_VERSION 51.49.0 |
|
36 |
+#define LIBAVCODEC_VERSION_INT ((51<<16)+(50<<8)+0) |
|
37 |
+#define LIBAVCODEC_VERSION 51.50.0 |
|
38 | 38 |
#define LIBAVCODEC_BUILD LIBAVCODEC_VERSION_INT |
39 | 39 |
|
40 | 40 |
#define LIBAVCODEC_IDENT "Lavc" AV_STRINGIFY(LIBAVCODEC_VERSION) |
... | ... |
@@ -284,6 +284,9 @@ enum CodecID { |
284 | 284 |
CODEC_ID_XSUB, |
285 | 285 |
CODEC_ID_SSA, |
286 | 286 |
|
287 |
+ /* other specific kind of codecs (generaly used for attachments) */ |
|
288 |
+ CODEC_ID_TTF= 0x18000, |
|
289 |
+ |
|
287 | 290 |
CODEC_ID_MPEG2TS= 0x20000, /**< _FAKE_ codec to indicate a raw MPEG-2 TS |
288 | 291 |
* stream (only used by libavformat) */ |
289 | 292 |
}; |
... | ... |
@@ -300,6 +303,7 @@ enum CodecType { |
300 | 300 |
CODEC_TYPE_AUDIO, |
301 | 301 |
CODEC_TYPE_DATA, |
302 | 302 |
CODEC_TYPE_SUBTITLE, |
303 |
+ CODEC_TYPE_ATTACHMENT, |
|
303 | 304 |
CODEC_TYPE_NB |
304 | 305 |
}; |
305 | 306 |
|
... | ... |
@@ -1219,6 +1219,10 @@ void avcodec_string(char *buf, int buf_size, AVCodecContext *enc, int encode) |
1219 | 1219 |
snprintf(buf, buf_size, "Subtitle: %s", codec_name); |
1220 | 1220 |
bitrate = enc->bit_rate; |
1221 | 1221 |
break; |
1222 |
+ case CODEC_TYPE_ATTACHMENT: |
|
1223 |
+ snprintf(buf, buf_size, "Attachment: %s", codec_name); |
|
1224 |
+ bitrate = enc->bit_rate; |
|
1225 |
+ break; |
|
1222 | 1226 |
default: |
1223 | 1227 |
snprintf(buf, buf_size, "Invalid Codec type %d", enc->codec_type); |
1224 | 1228 |
return; |
... | ... |
@@ -21,8 +21,8 @@ |
21 | 21 |
#ifndef FFMPEG_AVFORMAT_H |
22 | 22 |
#define FFMPEG_AVFORMAT_H |
23 | 23 |
|
24 |
-#define LIBAVFORMAT_VERSION_INT ((52<<16)+(5<<8)+0) |
|
25 |
-#define LIBAVFORMAT_VERSION 52.5.0 |
|
24 |
+#define LIBAVFORMAT_VERSION_INT ((52<<16)+(6<<8)+0) |
|
25 |
+#define LIBAVFORMAT_VERSION 52.6.0 |
|
26 | 26 |
#define LIBAVFORMAT_BUILD LIBAVFORMAT_VERSION_INT |
27 | 27 |
|
28 | 28 |
#define LIBAVFORMAT_IDENT "Lavf" AV_STRINGIFY(LIBAVFORMAT_VERSION) |
... | ... |
@@ -347,6 +347,8 @@ typedef struct AVStream { |
347 | 347 |
|
348 | 348 |
#define MAX_REORDER_DELAY 4 |
349 | 349 |
int64_t pts_buffer[MAX_REORDER_DELAY+1]; |
350 |
+ |
|
351 |
+ char *filename; /**< source filename of the stream */ |
|
350 | 352 |
} AVStream; |
351 | 353 |
|
352 | 354 |
#define AV_PROGRAM_RUNNING 1 |
... | ... |
@@ -71,3 +71,15 @@ const CodecTags ff_mkv_codec_tags[]={ |
71 | 71 |
{"" , CODEC_ID_NONE} |
72 | 72 |
/* TODO: AC3-9/10 (?), Real, Musepack, Quicktime */ |
73 | 73 |
}; |
74 |
+ |
|
75 |
+const CodecMime ff_mkv_mime_tags[] = { |
|
76 |
+ {"text/plain" , CODEC_ID_TEXT}, |
|
77 |
+ {"image/gif" , CODEC_ID_GIF}, |
|
78 |
+ {"image/jpeg" , CODEC_ID_MJPEG}, |
|
79 |
+ {"image/png" , CODEC_ID_PNG}, |
|
80 |
+ {"image/tiff" , CODEC_ID_TIFF}, |
|
81 |
+ {"application/x-truetype-font", CODEC_ID_TTF}, |
|
82 |
+ {"application/x-font" , CODEC_ID_TTF}, |
|
83 |
+ |
|
84 |
+ {"" , CODEC_ID_NONE} |
|
85 |
+}; |
... | ... |
@@ -55,6 +55,7 @@ |
55 | 55 |
#define MATROSKA_ID_CUES 0x1C53BB6B |
56 | 56 |
#define MATROSKA_ID_TAGS 0x1254C367 |
57 | 57 |
#define MATROSKA_ID_SEEKHEAD 0x114D9B74 |
58 |
+#define MATROSKA_ID_ATTACHMENTS 0x1941A469 |
|
58 | 59 |
#define MATROSKA_ID_CLUSTER 0x1F43B675 |
59 | 60 |
|
60 | 61 |
/* IDs in the info master */ |
... | ... |
@@ -138,6 +139,13 @@ |
138 | 138 |
#define MATROSKA_ID_BLOCKDURATION 0x9B |
139 | 139 |
#define MATROSKA_ID_BLOCKREFERENCE 0xFB |
140 | 140 |
|
141 |
+/* IDs in the attachments master */ |
|
142 |
+#define MATROSKA_ID_ATTACHEDFILE 0x61A7 |
|
143 |
+#define MATROSKA_ID_FILENAME 0x466E |
|
144 |
+#define MATROSKA_ID_FILEMIMETYPE 0x4660 |
|
145 |
+#define MATROSKA_ID_FILEDATA 0x465C |
|
146 |
+#define MATROSKA_ID_FILEUID 0x46AE |
|
147 |
+ |
|
141 | 148 |
typedef enum { |
142 | 149 |
MATROSKA_TRACK_TYPE_VIDEO = 0x1, |
143 | 150 |
MATROSKA_TRACK_TYPE_AUDIO = 0x2, |
... | ... |
@@ -185,6 +193,11 @@ typedef struct CodecTags{ |
185 | 185 |
enum CodecID id; |
186 | 186 |
}CodecTags; |
187 | 187 |
|
188 |
+typedef struct CodecMime{ |
|
189 |
+ char str[32]; |
|
190 |
+ enum CodecID id; |
|
191 |
+}CodecMime; |
|
192 |
+ |
|
188 | 193 |
#define MATROSKA_CODEC_ID_VIDEO_VFW_FOURCC "V_MS/VFW/FOURCC" |
189 | 194 |
#define MATROSKA_CODEC_ID_AUDIO_ACM "A_MS/ACM" |
190 | 195 |
|
... | ... |
@@ -192,5 +205,6 @@ typedef struct CodecTags{ |
192 | 192 |
#define EBML_MAX_DEPTH 16 |
193 | 193 |
|
194 | 194 |
extern const CodecTags ff_mkv_codec_tags[]; |
195 |
+extern const CodecMime ff_mkv_mime_tags[]; |
|
195 | 196 |
|
196 | 197 |
#endif /* FFMPEG_MATROSKA_H */ |
... | ... |
@@ -1865,6 +1865,119 @@ matroska_parse_seekhead (MatroskaDemuxContext *matroska) |
1865 | 1865 |
return res; |
1866 | 1866 |
} |
1867 | 1867 |
|
1868 |
+static int |
|
1869 |
+matroska_parse_attachments(AVFormatContext *s) |
|
1870 |
+{ |
|
1871 |
+ MatroskaDemuxContext *matroska = s->priv_data; |
|
1872 |
+ int res = 0; |
|
1873 |
+ uint32_t id; |
|
1874 |
+ |
|
1875 |
+ av_log(matroska->ctx, AV_LOG_DEBUG, "parsing attachments...\n"); |
|
1876 |
+ |
|
1877 |
+ while (res == 0) { |
|
1878 |
+ if (!(id = ebml_peek_id(matroska, &matroska->level_up))) { |
|
1879 |
+ res = AVERROR(EIO); |
|
1880 |
+ break; |
|
1881 |
+ } else if (matroska->level_up) { |
|
1882 |
+ matroska->level_up--; |
|
1883 |
+ break; |
|
1884 |
+ } |
|
1885 |
+ |
|
1886 |
+ switch (id) { |
|
1887 |
+ case MATROSKA_ID_ATTACHEDFILE: { |
|
1888 |
+ char* name = NULL; |
|
1889 |
+ char* mime = NULL; |
|
1890 |
+ uint8_t* data = NULL; |
|
1891 |
+ int i, data_size = 0; |
|
1892 |
+ AVStream *st; |
|
1893 |
+ |
|
1894 |
+ if ((res = ebml_read_master(matroska, &id)) < 0) |
|
1895 |
+ break; |
|
1896 |
+ |
|
1897 |
+ while (res == 0) { |
|
1898 |
+ if (!(id = ebml_peek_id(matroska, &matroska->level_up))) { |
|
1899 |
+ res = AVERROR(EIO); |
|
1900 |
+ break; |
|
1901 |
+ } else if (matroska->level_up) { |
|
1902 |
+ matroska->level_up--; |
|
1903 |
+ break; |
|
1904 |
+ } |
|
1905 |
+ |
|
1906 |
+ switch (id) { |
|
1907 |
+ case MATROSKA_ID_FILENAME: |
|
1908 |
+ res = ebml_read_utf8 (matroska, &id, &name); |
|
1909 |
+ break; |
|
1910 |
+ |
|
1911 |
+ case MATROSKA_ID_FILEMIMETYPE: |
|
1912 |
+ res = ebml_read_ascii (matroska, &id, &mime); |
|
1913 |
+ break; |
|
1914 |
+ |
|
1915 |
+ case MATROSKA_ID_FILEDATA: |
|
1916 |
+ res = ebml_read_binary(matroska, &id, &data, &data_size); |
|
1917 |
+ break; |
|
1918 |
+ |
|
1919 |
+ default: |
|
1920 |
+ av_log(matroska->ctx, AV_LOG_INFO, |
|
1921 |
+ "Unknown attachedfile ID 0x%x\n", id); |
|
1922 |
+ case EBML_ID_VOID: |
|
1923 |
+ res = ebml_read_skip(matroska); |
|
1924 |
+ break; |
|
1925 |
+ } |
|
1926 |
+ |
|
1927 |
+ if (matroska->level_up) { |
|
1928 |
+ matroska->level_up--; |
|
1929 |
+ break; |
|
1930 |
+ } |
|
1931 |
+ } |
|
1932 |
+ |
|
1933 |
+ if (!(name && mime && data && data_size > 0)) { |
|
1934 |
+ av_log(matroska->ctx, AV_LOG_ERROR, "incomplete attachment\n"); |
|
1935 |
+ break; |
|
1936 |
+ } |
|
1937 |
+ |
|
1938 |
+ st = av_new_stream(s, matroska->num_streams++); |
|
1939 |
+ if (st == NULL) |
|
1940 |
+ return AVERROR(ENOMEM); |
|
1941 |
+ st->filename = av_strdup(name); |
|
1942 |
+ st->codec->codec_id = CODEC_ID_NONE; |
|
1943 |
+ st->codec->codec_type = CODEC_TYPE_ATTACHMENT; |
|
1944 |
+ st->codec->extradata = av_malloc(data_size); |
|
1945 |
+ if(st->codec->extradata == NULL) |
|
1946 |
+ return AVERROR(ENOMEM); |
|
1947 |
+ st->codec->extradata_size = data_size; |
|
1948 |
+ memcpy(st->codec->extradata, data, data_size); |
|
1949 |
+ |
|
1950 |
+ for (i=0; ff_mkv_mime_tags[i].id != CODEC_ID_NONE; i++) { |
|
1951 |
+ if (!strncmp(ff_mkv_mime_tags[i].str, mime, |
|
1952 |
+ strlen(ff_mkv_mime_tags[i].str))) { |
|
1953 |
+ st->codec->codec_id = ff_mkv_mime_tags[i].id; |
|
1954 |
+ break; |
|
1955 |
+ } |
|
1956 |
+ } |
|
1957 |
+ |
|
1958 |
+ av_log(matroska->ctx, AV_LOG_DEBUG, "new attachment: %s, %s, size %d \n", name, mime, data_size); |
|
1959 |
+ break; |
|
1960 |
+ } |
|
1961 |
+ |
|
1962 |
+ default: |
|
1963 |
+ av_log(matroska->ctx, AV_LOG_INFO, |
|
1964 |
+ "Unknown attachments ID 0x%x\n", id); |
|
1965 |
+ /* fall-through */ |
|
1966 |
+ |
|
1967 |
+ case EBML_ID_VOID: |
|
1968 |
+ res = ebml_read_skip(matroska); |
|
1969 |
+ break; |
|
1970 |
+ } |
|
1971 |
+ |
|
1972 |
+ if (matroska->level_up) { |
|
1973 |
+ matroska->level_up--; |
|
1974 |
+ break; |
|
1975 |
+ } |
|
1976 |
+ } |
|
1977 |
+ |
|
1978 |
+ return res; |
|
1979 |
+} |
|
1980 |
+ |
|
1868 | 1981 |
#define ARRAY_SIZE(x) (sizeof(x)/sizeof(*x)) |
1869 | 1982 |
|
1870 | 1983 |
static int |
... | ... |
@@ -2007,6 +2120,13 @@ matroska_read_header (AVFormatContext *s, |
2007 | 2007 |
break; |
2008 | 2008 |
} |
2009 | 2009 |
|
2010 |
+ case MATROSKA_ID_ATTACHMENTS: { |
|
2011 |
+ if ((res = ebml_read_master(matroska, &id)) < 0) |
|
2012 |
+ break; |
|
2013 |
+ res = matroska_parse_attachments(s); |
|
2014 |
+ break; |
|
2015 |
+ } |
|
2016 |
+ |
|
2010 | 2017 |
case MATROSKA_ID_CLUSTER: { |
2011 | 2018 |
/* Do not read the master - this will be done in the next |
2012 | 2019 |
* call to matroska_read_packet. */ |