Beispiel #1
0
char *ebml_alloc_read_ascii (ebml_parser_t *ebml, ebml_elem_t *elem)
{
  char *text;
  if (elem->len >= 4096)
    return NULL;
  text = malloc(elem->len + 1);
  if (text)
  {
    text[elem->len] = '\0';
    if (ebml_read_ascii (ebml, elem, text))
      return text;
    free (text);
  }
  return NULL;
}
Beispiel #2
0
Datei: ebml.c Projekt: kax4/mpv
/*
 * Read the next element as a UTF-8 string.
 */
char *ebml_read_utf8(stream_t *s, uint64_t *length)
{
    return ebml_read_ascii(s, length);
}
Beispiel #3
0
/*
 * Read an EBML header.
 */
char *ebml_read_header(stream_t *s, int *version)
{
    uint64_t length, l, num;
    uint32_t id;
    char *str = NULL;

    if (ebml_read_master(s, &length) != EBML_ID_HEADER)
        return 0;

    if (version)
        *version = 1;

    while (length > 0) {
        id = ebml_read_id(s, NULL);
        if (id == EBML_ID_INVALID)
            return NULL;
        length -= 2;

        switch (id) {
            /* is our read version uptodate? */
        case EBML_ID_EBMLREADVERSION:
            num = ebml_read_uint(s, &l);
            if (num != EBML_VERSION)
                return NULL;
            break;

            /* we only handle 8 byte lengths at max */
        case EBML_ID_EBMLMAXSIZELENGTH:
            num = ebml_read_uint(s, &l);
            if (num != sizeof(uint64_t))
                return NULL;
            break;

            /* we handle 4 byte IDs at max */
        case EBML_ID_EBMLMAXIDLENGTH:
            num = ebml_read_uint(s, &l);
            if (num != sizeof(uint32_t))
                return NULL;
            break;

        case EBML_ID_DOCTYPE:
            str = ebml_read_ascii(s, &l);
            if (str == NULL)
                return NULL;
            break;

        case EBML_ID_DOCTYPEREADVERSION:
            num = ebml_read_uint(s, &l);
            if (num == EBML_UINT_INVALID)
                return NULL;
            if (version)
                *version = num;
            break;

            /* we ignore these two, they don't tell us anything we care about */
        case EBML_ID_VOID:
        case EBML_ID_EBMLVERSION:
        case EBML_ID_DOCTYPEVERSION:
        default:
            if (ebml_read_skip(s, &l))
                return NULL;
            break;
        }
        length -= l;
    }

    return str;
}
Beispiel #4
0
int ebml_read_utf8 (ebml_parser_t *ebml, ebml_elem_t *elem, char *str) {
  return ebml_read_ascii (ebml, elem, str);
}
static int
demux_mkv_read_trackentry (FILE *s, mkv_demuxer_t *mkv_d)
{
  mkv_track_t *track;
  uint64_t len, length, l;
  int il;

  track = (mkv_track_t *)calloc (1, sizeof (*track));
  /* set default values */
  track->default_track = 1;
  track->name = 0;
  track->language = strdup("eng");

  len = length = ebml_read_length (s, &il);
  len += il;
  while (length > 0)
    {
      switch (ebml_read_id (s, &il))
        {
        case MATROSKA_ID_TRACKNUMBER:
          {
            uint64_t num = ebml_read_uint (s, &l);
            if (num == EBML_UINT_INVALID)
              goto err_out;
            track->tnum = num;
            mp_msg (MSGT_DEMUX, MSGL_V, "[mkv] |  + Track number: %u\n",
                    track->tnum);
            break;
          }

        case MATROSKA_ID_TRACKNAME:
          {
            track->name = ebml_read_utf8 (s, &l);
            if (track->name == NULL)
              goto err_out;
            mp_msg (MSGT_DEMUX, MSGL_V, "[mkv] |  + Name: %s\n",
                    track->name);
            break;
          }

        case MATROSKA_ID_TRACKTYPE:
          {
            uint64_t num = ebml_read_uint (s, &l);
            if (num == EBML_UINT_INVALID)
              goto err_out;
            track->type = num;
            mp_msg (MSGT_DEMUX, MSGL_V, "[mkv] |  + Track type: ");
            switch (track->type)
              {
              case MATROSKA_TRACK_AUDIO:
                mp_msg (MSGT_DEMUX, MSGL_V, "Audio\n");
                break;
              case MATROSKA_TRACK_VIDEO:
                mp_msg (MSGT_DEMUX, MSGL_V, "Video\n");
                break;
              case MATROSKA_TRACK_SUBTITLE:
                mp_msg (MSGT_DEMUX, MSGL_V, "Subtitle\n");
                break;
              default:
                mp_msg (MSGT_DEMUX, MSGL_V, "unknown\n");
                break;
            }
            break;
          }

        case MATROSKA_ID_TRACKAUDIO:
          mp_msg (MSGT_DEMUX, MSGL_V, "[mkv] |  + Audio track\n");
          l = demux_mkv_read_trackaudio (s, track);
          if (l == 0)
            goto err_out;
          break;

        case MATROSKA_ID_TRACKVIDEO:
          mp_msg (MSGT_DEMUX, MSGL_V, "[mkv] |  + Video track\n");
          l = demux_mkv_read_trackvideo (s, track);
          if (l == 0)
            goto err_out;
          break;

        case MATROSKA_ID_CODECID:
          track->codec_id = ebml_read_ascii (s, &l);
          if (track->codec_id == NULL)
            goto err_out;
          if (!strcmp (track->codec_id, MKV_V_MSCOMP) ||
              !strcmp (track->codec_id, MKV_A_ACM))
            track->ms_compat = 1;
          else if (!strcmp (track->codec_id, MKV_S_VOBSUB))
            track->subtitle_type = MATROSKA_SUBTYPE_VOBSUB;
          else if (!strcmp (track->codec_id, MKV_S_TEXTSSA)
                   || !strcmp (track->codec_id, MKV_S_TEXTASS)
                   || !strcmp (track->codec_id, MKV_S_SSA)
                   || !strcmp (track->codec_id, MKV_S_ASS))
            {
              track->subtitle_type = MATROSKA_SUBTYPE_SSA;
            }
          else if (!strcmp (track->codec_id, MKV_S_TEXTASCII))
            track->subtitle_type = MATROSKA_SUBTYPE_TEXT;
          if (!strcmp (track->codec_id, MKV_S_TEXTUTF8))
            {
              track->subtitle_type = MATROSKA_SUBTYPE_TEXT;
            }
          mp_msg (MSGT_DEMUX, MSGL_V, "[mkv] |  + Codec ID: %s\n",
                  track->codec_id);
          break;

        case MATROSKA_ID_CODECPRIVATE:
          {
            int x;
            uint64_t num = ebml_read_length (s, &x);
	    // audit: cheap guard against overflows later..
	    if (num > SIZE_MAX - 1000)
              goto err_out;
            l = x + num;
            track->private_data = malloc (num + AV_LZO_INPUT_PADDING);
            if (read_data(s, track->private_data, num) != (size_t) num)
              goto err_out;
            track->private_size = num;
            mp_msg (MSGT_DEMUX, MSGL_V, "[mkv] |  + CodecPrivate, length "
                    "%u\n", track->private_size);
			if( track->type == MATROSKA_TRACK_VIDEO &&
					!strcmp(track->codec_id,MKV_V_MPEG4_AVC)
			  )
			{
				unsigned char*  ptr, *hdr;
				int write_len=0;
				int avc1_header_size = 0;

				ptr = (unsigned char *)track->private_data + 7; //skip 01 64 00 29 FF E1 00 and seek to first header len pos.

				unsigned char *avc1_header = (unsigned char *)malloc (track->private_size + AV_LZO_INPUT_PADDING);
				hdr = avc1_header;

				write_len = *ptr++; //get first header len

				hdr[0] = hdr[1] = hdr[2] = 0;
				hdr[3] = (unsigned char)write_len;
				hdr += 4;

				memcpy(hdr, ptr, write_len);
				hdr += write_len;
				ptr += write_len;

				avc1_header_size += 4 + write_len;

				mp_msg(MSGT_DEMUX, MSGL_V, "1write_len[%d]\n",write_len);//SkyMedi_Vincent

				ptr += 2;   //skip 01 00 and seek to second header len pos.
				write_len = *ptr++; //get second header len

				hdr[0] = hdr[1] = hdr[2] = 0;
				hdr[3] = (unsigned char)write_len;
				hdr += 4;

				memcpy(hdr, ptr, write_len);

				avc1_header_size += 4 + write_len;

				mp_msg(MSGT_DEMUX, MSGL_V, "2write_len[%d]\n",write_len);//SkyMedi_Vincent
				mp_msg(MSGT_DEMUX, MSGL_V, "avc1_header_size = %d\n", avc1_header_size);
				{
					int i = 0;
					for( i = 0 ; i< avc1_header_size; i++)
						mp_msg(MSGT_DEMUX, MSGL_V, "%02X ", avc1_header[i]);
					mp_msg(MSGT_DEMUX, MSGL_V, "\n");
				}

				if (!check_avc1_sps_bank0(avc1_header+5, avc1_header_size-5))
					goto err_out;

				free(avc1_header);
			}
            break;
          }

        case MATROSKA_ID_TRACKLANGUAGE:
          free(track->language);
          track->language = ebml_read_utf8 (s, &l);
          if (track->language == NULL)
            goto err_out;
          mp_msg (MSGT_DEMUX, MSGL_V, "[mkv] |  + Language: %s\n",
                  track->language);
          break;

        case MATROSKA_ID_TRACKFLAGDEFAULT:
          {
            uint64_t num = ebml_read_uint (s, &l);
            if (num == EBML_UINT_INVALID)
              goto err_out;
            track->default_track = num;
            mp_msg (MSGT_DEMUX, MSGL_V, "[mkv] |  + Default flag: %u\n",
                    track->default_track);
            break;
          }

        case MATROSKA_ID_TRACKDEFAULTDURATION:
          {
            uint64_t num = ebml_read_uint (s, &l);
            if (num == EBML_UINT_INVALID)
              goto err_out;
            if (num == 0)
              mp_msg (MSGT_DEMUX, MSGL_V, "[mkv] |  + Default duration: 0");
            else
              {
                track->v_frate = 1000000000.0 / num;
                track->default_duration = num / 1000000000.0;
                mp_msg (MSGT_DEMUX, MSGL_V, "[mkv] |  + Default duration: "
                        "%.3fms ( = %.3f fps)\n",num/1000000.0,track->v_frate);
              }
            break;
          }

        case MATROSKA_ID_TRACKENCODINGS:
          l = demux_mkv_read_trackencodings (s, track);
          if (l == 0)
            goto err_out;
          break;

        default:
          ebml_read_skip (s, &l);
          break;
        }
      length -= l + il;
    }

  mkv_d->tracks[mkv_d->num_tracks++] = track;
  return len;

err_out:
  demux_mkv_free_trackentry(track);
  return 0;
}