libextractor

GNU libextractor
Log | Files | Refs | Submodules | README | LICENSE

commit a30cc7ad006baac3156b69ba51cffb83f367c4d0
parent ba90dc573961d9daa855bd423a47b61d958b47c6
Author: Christian Grothoff <christian@grothoff.org>
Date:   Sat, 19 Nov 2011 14:35:25 +0000

some mkv code cleanup

Diffstat:
Msrc/plugins/mkv_extractor.c | 267+++++++++++++++++++++++++++++++++++++++++++++++--------------------------------
1 file changed, 159 insertions(+), 108 deletions(-)

diff --git a/src/plugins/mkv_extractor.c b/src/plugins/mkv_extractor.c @@ -26,14 +26,28 @@ #include "platform.h" #include "extractor.h" - +#include <stdint.h> #define ADD(s,t) do { if (0 != (ret = proc (proc_cls, "mkv", t, EXTRACTOR_METAFORMAT_UTF8, "text/plain", s, strlen(s)+1))) goto EXIT; } while (0) +/** + * FIXME: document + */ #define BUFFER_SIZE 0x4000 + +/** + * FIXME: document + */ #define MAX_STRING_SIZE 1024 + +/** + * FIXME: document + */ #define MAX_STREAMS 9 -typedef long long int64; + +/** + * FIXME: document + */ enum { MKV_Track_video = 1, @@ -41,6 +55,10 @@ enum MKV_Track_subtitle = 3, MKV_Track_subtitle_orig = 0x11 }; + +/** + * FIXME: document + */ enum { MKVID_OutputSamplingFrequency = 0x78B5, @@ -73,103 +91,113 @@ enum }; -static int -VINTparse (const unsigned char *buffer, const int start, const int end, - int64 * result, const int flag) +/** + * FIXME: document 'flag', should 'temp'/'result' really be signed? + * + * @return 0 on error, otherwise number of bytes read from buffer + */ +static size_t +VINTparse (const unsigned char *buffer, size_t start, size_t end, + int64_t * result, int flag) { - unsigned const char mask[8] = { 0x80, 0x40, 0x20, 0x10, 0x8, 0x4, 0x2, 0x1 }; - unsigned const char imask[8] = { 0x7F, 0x3F, 0x1F, 0xF, 0x7, 0x3, 0x1, 00 }; - int VINT_WIDTH; - int c; - - VINT_WIDTH = 0; - int64 temp; + static const unsigned char mask[8] = { 0x80, 0x40, 0x20, 0x10, 0x8, 0x4, 0x2, 0x1 }; + static const unsigned char imask[8] = { 0x7F, 0x3F, 0x1F, 0xF, 0x7, 0x3, 0x1, 00 }; + int vint_width; + unsigned int c; + int64_t temp; unsigned char tempc; - *result = 0; - if (end - start < 2) - { - return 0; /*ops */ - } + if (end - start < 2) + return 0; /*ops */ + vint_width = 0; for (c = 0; c < 8; c++) if (!(buffer[start] & mask[c])) - VINT_WIDTH++; + vint_width++; else break; - if (VINT_WIDTH >= 8 || VINT_WIDTH + start + 1 >= end) - { + if ( (vint_width >= 8) || (vint_width + start + 1 >= end) ) return 0; - } - for (c = 0; c < VINT_WIDTH; c++) + *result = 0; + for (c = 0; c < vint_width; c++) { - tempc = buffer[start + VINT_WIDTH - c]; + tempc = buffer[start + vint_width - c]; temp = tempc << (c * 8); *result += temp; } - if (flag) - *result += (buffer[start] & imask[VINT_WIDTH]) << (VINT_WIDTH * 8); + *result += (buffer[start] & imask[vint_width]) << (vint_width * 8); else - *result += (buffer[start]) << (VINT_WIDTH * 8); - - return VINT_WIDTH + 1; + *result += (buffer[start]) << (vint_width * 8); + return vint_width + 1; } + +/** + * FIXME: 'unsigned int' or 'uint32_t' for ID? + * FIXME: document arguments, return value... + */ static int -elementRead (const char *buffer, const int start, const int end, - unsigned int *ID, int64 * size) +elementRead (const unsigned char *buffer, size_t start, size_t end, + unsigned int *id, int64_t * size) { - int64 tempID; - int64 tempsize; - int ID_offset, size_offset; + int64_t tempID; + int64_t tempsize; + size_t id_offset; + size_t size_offset; tempID = 0; - ID_offset = VINTparse (buffer, start, end, &tempID, 0); - if (!ID_offset) + id_offset = VINTparse (buffer, start, end, &tempID, 0); + if (!id_offset) return 0; - size_offset = VINTparse (buffer, start + ID_offset, end, &tempsize, 1); + size_offset = VINTparse (buffer, start + id_offset, end, &tempsize, 1); if (!size_offset) return 0; - *ID = (int) tempID; /*id must be <4 and must to feet in uint */ + *id = (unsigned int) tempID; /*id must be <4 and must fit in uint */ *size = tempsize; - return ID_offset + size_offset; + return id_offset + size_offset; } -static int64 -getInt (const char *buffer, const int start, const int size) + +/** + * FIXME: signed or unsigned return value? + */ +static int64_t +getInt (const unsigned char *buffer, size_t start, size_t size) { -/*return a int [8-64], from buffer, Big Endian*/ - int64 result = 0; - int c; + /*return a int [8-64], from buffer, Big Endian*/ + int64_t result; + size_t c; + result = 0; for (c = 1; c <= size; c++) - { - result += buffer[start + c - 1] << (8 * (size - c)); - } + result += buffer[start + c - 1] << (8 * (size - c)); return result; } static float -getFloat (const char *buffer, const int start, const int size) +getFloat (const char *buffer, size_t start, size_t size) { - float result = 0; + float result; char tmp[4]; + if (size != sizeof (float)) + return 0.0; if (size == sizeof (float)) { tmp[0] = buffer[start + 3]; tmp[1] = buffer[start + 2]; tmp[2] = buffer[start + 1]; tmp[3] = buffer[start]; - result = *((float *) (tmp)); + return *((float *) (tmp)); } return result; } -const unsigned int MKV_Parse_list[] = { /*Elements, containing requed information (sub-elements), see enum in mkv.h for values */ +static const unsigned int MKV_Parse_list[] = { + /*Elements, containing requed information (sub-elements), see enum in mkv.h for values */ MKVID_Segment, MKVID_Info, MKVID_Video, @@ -178,26 +206,26 @@ const unsigned int MKV_Parse_list[] = { /*Elements, containing requed informatio MKVID_Tracks }; -const char stream_type_letters[] = "?vat"; /*[0]-no, [1]-video,[2]-audio,[3]-text */ +static const char stream_type_letters[] = "?vat"; /*[0]-no, [1]-video,[2]-audio,[3]-text */ /* video/mkv */ int -EXTRACTOR_mkv_extract (const unsigned char *data, size_t size1, +EXTRACTOR_mkv_extract (const unsigned char *data, size_t size, EXTRACTOR_MetaDataProcessor proc, void *proc_cls, const char *options) { int ret; - char buffer[128],temp[128]; - int p; /*pointer in buffer */ + char buffer[128]; + char temp[128]; + size_t p; /*pointer in buffer */ int c, c2; /*counter in some loops */ - unsigned int eID; /*element ID */ - int64 eSize; /*Size of element content */ + int64_t eSize; /*Size of element content */ int offs; - int64 timescale = 1000000; - float Duration = 0; - int64 DefaultDuration = 0; + int64_t timescale = 1000000; + float duration = -1.0; + int64_t DefaultDuration = 0; int TrackType = 0; int pvt_look_flag = 0; int curr_c = -1; @@ -207,34 +235,20 @@ EXTRACTOR_mkv_extract (const unsigned char *data, size_t size1, int value_width = 0; int value_height = 0; int value = 0; - int size; + size_t size1; + const unsigned char *start; - ret = 0; - p = 0; - - if (size1 > 16777216) - { - size = 16777216; - }else{ - size = size1; - } - - if (!size) - { + if (size > 32 * 1024) + size1 = 32 * 1024; + else + size1 = size; + start = memchr (data, MKVID_FILE_BEGIN, size1); + if (NULL == start) return 0; - } - - - while (data[p] != MKVID_FILE_BEGIN) - { - p++; - if (p >= size) - { - return 0; - } - }; /*skip text while EBML begin */ - + p = start - data; + /*main loop*/ + ret = 0; do { offs = elementRead (data, p, size, &eID, &eSize); @@ -264,18 +278,32 @@ EXTRACTOR_mkv_extract (const unsigned char *data, size_t size1, v_c++; if (v_c > MAX_STREAMS) v_c = MAX_STREAMS; - sprintf (buffer, "%u(video)", - (int) (Duration / 1e+9 * (float) timescale)); - ADD (buffer, EXTRACTOR_METATYPE_DURATION); + if (duration != -1.0) + { + /* FIXME: duration might still be -1 here, defer until + end of function & check if duration is != -1 */ + snprintf (buffer, + sizeof(buffer), + "%u s (video)", + (int) (duration / 1e+9 * (float) timescale)); + ADD (buffer, EXTRACTOR_METATYPE_DURATION); + } curr_c = v_c; break; case MKV_Track_audio: a_c++; if (a_c > MAX_STREAMS) a_c = MAX_STREAMS; - sprintf (buffer, "%u(audio)", - (int) (Duration / 1e+9 * (float) timescale)); - ADD (buffer, EXTRACTOR_METATYPE_DURATION); + if (duration != -1.0) + { + /* FIXME: duration might still be -1 here, defer until + end of function & check if duration is != -1 */ + snprintf (buffer, + sizeof (buffer), + "%u s (audio)", + (unsigned int) (duration / 1e+9 * (float) timescale)); + ADD (buffer, EXTRACTOR_METATYPE_DURATION); + } curr_c = a_c; break; case MKV_Track_subtitle_orig: @@ -293,7 +321,10 @@ EXTRACTOR_mkv_extract (const unsigned char *data, size_t size1, DefaultDuration = value; if (DefaultDuration > 100) { - sprintf (buffer, "fps: %u", 1000000000 / DefaultDuration); + /* FIXME: integrate with codec name/id into 'METATYPE_FORMAT' */ + snprintf (buffer, + sizeof (buffer), + "fps: %u", 1000000000 / DefaultDuration); ADD (buffer, EXTRACTOR_METATYPE_UNKNOWN); } } @@ -301,9 +332,12 @@ EXTRACTOR_mkv_extract (const unsigned char *data, size_t size1, case MKVID_Language: /*stream language */ if (curr_c >= 0 && TrackType < 4 && eSize < MAX_STRING_SIZE) { - strncpy(temp,data+p,eSize); - temp[eSize] = '\0'; - sprintf (buffer, "%s", temp); + /* FIXME: why first temp, then buffer? */ + snprintf (buffer, + sizeof (buffer), + "%.*s", + (int) eSize, + data + p); ADD (buffer, EXTRACTOR_METATYPE_LANGUAGE); } break; @@ -311,12 +345,15 @@ EXTRACTOR_mkv_extract (const unsigned char *data, size_t size1, case MKVID_CodecID: /*codec detection (if V_MS/VFW/FOURCC - set a fourcc code, else fill a vcodecs value) */ if (curr_c >= 0 && TrackType < 4 && eSize < MAX_STRING_SIZE) { - strncpy(temp,data+p,eSize); - temp[eSize] = '\0'; - if (!strcmp (temp, "V_MS/VFW/FOURCC")) + if (!strncmp (data + p, "V_MS/VFW/FOURCC", eSize)) pvt_look_flag = 1; - sprintf (buffer, "codec: %s", temp); - ADD (buffer, EXTRACTOR_METATYPE_UNKNOWN); + snprintf (buffer, + sizeof (buffer), + "codec: %.*s", + (int) eSize, + data + p); + ADD (buffer, + EXTRACTOR_METATYPE_FORMAT); } break; case MKVID_CodecPrivate: @@ -344,25 +381,36 @@ EXTRACTOR_mkv_extract (const unsigned char *data, size_t size1, break; case MKVID_TimeCodeScale: timescale = getInt (data, p, eSize); - sprintf (buffer, "TimeScale: %u", timescale); + snprintf (buffer, + sizeof (buffer), + "TimeScale: %u", timescale); ADD (buffer, EXTRACTOR_METATYPE_UNKNOWN); break; case MKVID_Duration: - Duration = getFloat (data, p, eSize); - sprintf (buffer, "duration: %u s", Duration); + duration = getFloat (data, p, eSize); + snprintf (buffer, + sizeof (buffer), + "%f ms", duration); ADD (buffer, EXTRACTOR_METATYPE_DURATION); break; case MKVID_Channels: - sprintf (buffer, "channels: %u", value); + snprintf (buffer, + sizeof (buffer), + "channels: %u", value); ADD (buffer, EXTRACTOR_METATYPE_UNKNOWN); break; case MKVID_BitDepth: - sprintf (buffer, "BitDepth: %u", value); + snprintf (buffer, + sizeof (buffer), + "BitDepth: %u", value); ADD (buffer, EXTRACTOR_METATYPE_UNKNOWN); break; case MKVID_OutputSamplingFrequency: /*pasthough */ case MKVID_SamplingFrequency: - sprintf (buffer, "Sampling Frequency: %u", value); + /* FIXME: the resulting value seems wrong... Unit? */ + snprintf (buffer, + sizeof (buffer), + "Sampling Frequency: %u", value); ADD (buffer, EXTRACTOR_METATYPE_UNKNOWN); break; break; @@ -378,9 +426,12 @@ EXTRACTOR_mkv_extract (const unsigned char *data, size_t size1, p += eSize; /*skip unknown or uninteresting */ } while (1); - - sprintf (buffer, "Image dimensions: %u X %u", value_width, value_height); - ADD (buffer, EXTRACTOR_METATYPE_UNKNOWN); + if ( (value_width != 0) && (value_height != 0) ) + snprintf (buffer, + sizeof(buffer), + "%ux%u", + value_width, value_height); + ADD (buffer, EXTRACTOR_METATYPE_IMAGE_DIMENSIONS); EXIT: