Add support for H.264/AAC and some other audio codecs to the Flash
demuxer. From Xine-lib repo ok jakemsr@
This commit is contained in:
parent
8a039dc0a7
commit
4db68789cb
@ -1,4 +1,4 @@
|
||||
# $OpenBSD: Makefile,v 1.40 2008/09/15 22:11:42 jakemsr Exp $
|
||||
# $OpenBSD: Makefile,v 1.41 2008/09/16 02:37:04 brad Exp $
|
||||
|
||||
SHARED_ONLY= Yes
|
||||
|
||||
@ -9,7 +9,7 @@ COMMENT-jack= jackd audio output module for xine-lib
|
||||
|
||||
V= 1.1.15
|
||||
DISTNAME= xine-lib-${V}
|
||||
PKGNAME-main= ${DISTNAME}p2
|
||||
PKGNAME-main= ${DISTNAME}p3
|
||||
PKGNAME-esd= xine-lib-esd-${V}
|
||||
PKGNAME-arts= xine-lib-arts-${V}
|
||||
PKGNAME-jack= xine-lib-jack-${V}
|
||||
|
378
multimedia/xine-lib/patches/patch-src_demuxers_demux_flv_c
Normal file
378
multimedia/xine-lib/patches/patch-src_demuxers_demux_flv_c
Normal file
@ -0,0 +1,378 @@
|
||||
$OpenBSD: patch-src_demuxers_demux_flv_c,v 1.1 2008/09/16 02:37:04 brad Exp $
|
||||
--- src/demuxers/demux_flv.c.orig Sat Jun 14 19:15:00 2008
|
||||
+++ src/demuxers/demux_flv.c Fri Sep 5 20:52:34 2008
|
||||
@@ -21,10 +21,10 @@
|
||||
/*
|
||||
* Flash Video (.flv) File Demuxer
|
||||
* by Mike Melanson (melanson@pcisys.net) and
|
||||
- * Claudio Ciccani (klan@directfb.org)
|
||||
+ * Claudio Ciccani (klan@users.sf.net)
|
||||
*
|
||||
* For more information on the FLV file format, visit:
|
||||
- * http://download.macromedia.com/pub/flash/flash_file_format_specification.pdf
|
||||
+ * http://www.adobe.com/devnet/flv/pdf/video_file_format_spec_v9.pdf
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
@@ -110,14 +110,20 @@ typedef struct {
|
||||
#define FLV_SOUND_FORMAT_ADPCM 0x01
|
||||
#define FLV_SOUND_FORMAT_MP3 0x02
|
||||
#define FLV_SOUND_FORMAT_PCM_LE 0x03
|
||||
+#define FLV_SOUND_FORMAT_NELLY16 0x04 /* Nellymoser 16KHz */
|
||||
#define FLV_SOUND_FORMAT_NELLY8 0x05 /* Nellymoser 8KHz */
|
||||
#define FLV_SOUND_FORMAT_NELLY 0x06 /* Nellymoser */
|
||||
+#define FLV_SOUND_FORMAT_ALAW 0x07 /* G.711 A-LAW */
|
||||
+#define FLV_SOUND_FORMAT_MULAW 0x08 /* G.711 MU-LAW */
|
||||
+#define FLV_SOUND_FORMAT_AAC 0x0a
|
||||
+#define FLV_SOUND_FORMAT_MP38 0x0e /* MP3 8KHz */
|
||||
|
||||
#define FLV_VIDEO_FORMAT_FLV1 0x02 /* Sorenson H.263 */
|
||||
#define FLV_VIDEO_FORMAT_SCREEN 0x03
|
||||
#define FLV_VIDEO_FORMAT_VP6 0x04 /* On2 VP6 */
|
||||
#define FLV_VIDEO_FORMAT_VP6A 0x05 /* On2 VP6 with alphachannel */
|
||||
#define FLV_VIDEO_FORMAT_SCREEN2 0x06
|
||||
+#define FLV_VIDEO_FORMAT_H264 0x07
|
||||
|
||||
#define FLV_DATA_TYPE_NUMBER 0x00
|
||||
#define FLV_DATA_TYPE_BOOL 0x01
|
||||
@@ -429,11 +435,24 @@ static int read_flv_packet(demux_flv_t *this, int prev
|
||||
buf_type = BUF_AUDIO_FLVADPCM;
|
||||
break;
|
||||
case FLV_SOUND_FORMAT_MP3:
|
||||
+ case FLV_SOUND_FORMAT_MP38:
|
||||
buf_type = BUF_AUDIO_MPEG;
|
||||
break;
|
||||
case FLV_SOUND_FORMAT_PCM_LE:
|
||||
buf_type = BUF_AUDIO_LPCM_LE;
|
||||
break;
|
||||
+ case FLV_SOUND_FORMAT_ALAW:
|
||||
+ buf_type = BUF_AUDIO_ALAW;
|
||||
+ break;
|
||||
+ case FLV_SOUND_FORMAT_MULAW:
|
||||
+ buf_type = BUF_AUDIO_MULAW;
|
||||
+ break;
|
||||
+ case FLV_SOUND_FORMAT_AAC:
|
||||
+ buf_type = BUF_AUDIO_AAC;
|
||||
+ /* AAC extra header */
|
||||
+ this->input->read(this->input, buffer, 1 );
|
||||
+ remaining_bytes--;
|
||||
+ break;
|
||||
default:
|
||||
lprintf(" unsupported audio format (%d)...\n", buffer[0] >> 4);
|
||||
buf_type = BUF_AUDIO_UNKNOWN;
|
||||
@@ -464,8 +483,17 @@ static int read_flv_packet(demux_flv_t *this, int prev
|
||||
}
|
||||
remaining_bytes--;
|
||||
|
||||
- if ((buffer[0] >> 4) == 0x01)
|
||||
- buf_flags = BUF_FLAG_KEYFRAME;
|
||||
+ switch ((buffer[0] >> 4)) {
|
||||
+ case 0x01:
|
||||
+ buf_flags = BUF_FLAG_KEYFRAME;
|
||||
+ break;
|
||||
+ case 0x05:
|
||||
+ /* skip server command */
|
||||
+ this->input->seek(this->input, remaining_bytes, SEEK_CUR);
|
||||
+ continue;
|
||||
+ default:
|
||||
+ break;
|
||||
+ }
|
||||
|
||||
this->videocodec = buffer[0] & 0x0F; /* override */
|
||||
switch (this->videocodec) {
|
||||
@@ -484,6 +512,12 @@ static int read_flv_packet(demux_flv_t *this, int prev
|
||||
this->input->read(this->input, buffer, 4);
|
||||
remaining_bytes -= 4;
|
||||
break;
|
||||
+ case FLV_VIDEO_FORMAT_H264:
|
||||
+ buf_type = BUF_VIDEO_H264;
|
||||
+ /* AVC extra header */
|
||||
+ this->input->read(this->input, buffer, 4);
|
||||
+ remaining_bytes -= 4;
|
||||
+ break;
|
||||
default:
|
||||
lprintf(" unsupported video format (%d)...\n", buffer[0] & 0x0F);
|
||||
buf_type = BUF_VIDEO_UNKNOWN;
|
||||
@@ -511,6 +545,23 @@ static int read_flv_packet(demux_flv_t *this, int prev
|
||||
bih->biSize++;
|
||||
buf->size++;
|
||||
}
|
||||
+ else if (buf_type == BUF_VIDEO_H264 && buffer[0] == 0) {
|
||||
+ /* AVC sequence header */
|
||||
+ if (remaining_bytes > buf->max_size-buf->size) {
|
||||
+ xprintf(this->xine, XINE_VERBOSITY_LOG,
|
||||
+ _("sequence header too big (%u bytes)!\n"), remaining_bytes);
|
||||
+ this->input->read(this->input, buf->content+buf->size, buf->max_size-buf->size);
|
||||
+ this->input->seek(this->input, remaining_bytes-buf->max_size-buf->size, SEEK_CUR);
|
||||
+ bih->biSize = buf->max_size;
|
||||
+ buf->size = buf->max_size;
|
||||
+ }
|
||||
+ else {
|
||||
+ this->input->read(this->input, buf->content+buf->size, remaining_bytes);
|
||||
+ bih->biSize += remaining_bytes;
|
||||
+ buf->size += remaining_bytes;
|
||||
+ }
|
||||
+ remaining_bytes = 0;
|
||||
+ }
|
||||
fifo->put(fifo, buf);
|
||||
this->got_video_header = 1;
|
||||
}
|
||||
@@ -537,11 +588,21 @@ static int read_flv_packet(demux_flv_t *this, int prev
|
||||
buf->type = BUF_AUDIO_FLVADPCM;
|
||||
break;
|
||||
case FLV_SOUND_FORMAT_MP3:
|
||||
+ case FLV_SOUND_FORMAT_MP38:
|
||||
buf->type = BUF_AUDIO_MPEG;
|
||||
break;
|
||||
case FLV_SOUND_FORMAT_PCM_LE:
|
||||
buf->type = BUF_AUDIO_LPCM_LE;
|
||||
break;
|
||||
+ case FLV_SOUND_FORMAT_ALAW:
|
||||
+ buf->type = BUF_AUDIO_ALAW;
|
||||
+ break;
|
||||
+ case FLV_SOUND_FORMAT_MULAW:
|
||||
+ buf->type = BUF_AUDIO_MULAW;
|
||||
+ break;
|
||||
+ case FLV_SOUND_FORMAT_AAC:
|
||||
+ buf->type = BUF_AUDIO_AAC;
|
||||
+ break;
|
||||
default:
|
||||
buf->type = BUF_AUDIO_UNKNOWN;
|
||||
break;
|
||||
@@ -549,9 +610,10 @@ static int read_flv_packet(demux_flv_t *this, int prev
|
||||
buf->size = 0;
|
||||
this->audio_fifo->put(this->audio_fifo, buf);
|
||||
this->got_audio_header = 1;
|
||||
+ lprintf(" got audio header from metadata...\n");
|
||||
}
|
||||
|
||||
- if (!this->got_video_header && this->videocodec) {
|
||||
+ if (!this->got_video_header && this->videocodec && this->videocodec != FLV_VIDEO_FORMAT_H264) {
|
||||
xine_bmiheader *bih;
|
||||
buf = this->video_fifo->buffer_pool_alloc(this->video_fifo);
|
||||
buf->decoder_flags = BUF_FLAG_HEADER | BUF_FLAG_STDHEADER |
|
||||
@@ -583,6 +645,7 @@ static int read_flv_packet(demux_flv_t *this, int prev
|
||||
}
|
||||
this->video_fifo->put(this->video_fifo, buf);
|
||||
this->got_video_header = 1;
|
||||
+ lprintf(" got video header from metadata...\n");
|
||||
}
|
||||
|
||||
return this->status;
|
||||
@@ -600,33 +663,61 @@ static int read_flv_packet(demux_flv_t *this, int prev
|
||||
while (remaining_bytes) {
|
||||
buf = fifo->buffer_pool_alloc(fifo);
|
||||
buf->type = buf_type;
|
||||
- buf->pts = (int64_t) pts * 90;
|
||||
|
||||
- if (!preview)
|
||||
- check_newpts(this, buf->pts, (tag_type == FLV_TAG_TYPE_VIDEO));
|
||||
-
|
||||
buf->extra_info->input_time = pts;
|
||||
if (this->input->get_length(this->input)) {
|
||||
buf->extra_info->input_normpos =
|
||||
(int)((double)this->input->get_current_pos(this->input) * 65535.0 / this->size);
|
||||
}
|
||||
+
|
||||
+ if ((buf_type == BUF_VIDEO_H264 || buf_type == BUF_AUDIO_AAC) && buffer[0] == 0) {
|
||||
+ /* AVC/AAC sequence header */
|
||||
+ buf->pts = 0;
|
||||
+ buf->size = 0;
|
||||
+
|
||||
+ buf->decoder_flags = BUF_FLAG_SPECIAL | BUF_FLAG_HEADER;
|
||||
+ if (preview)
|
||||
+ buf->decoder_flags |= BUF_FLAG_PREVIEW;
|
||||
|
||||
- if (remaining_bytes > buf->max_size)
|
||||
- buf->size = buf->max_size;
|
||||
- else
|
||||
- buf->size = remaining_bytes;
|
||||
- remaining_bytes -= buf->size;
|
||||
+ buf->decoder_info[1] = BUF_SPECIAL_DECODER_CONFIG;
|
||||
+ buf->decoder_info[2] = MIN(remaining_bytes, buf->max_size);
|
||||
+ buf->decoder_info_ptr[2] = buf->mem;
|
||||
+
|
||||
+ if (this->input->read(this->input, buf->mem, buf->decoder_info[2]) != buf->decoder_info[2]) {
|
||||
+ buf->free_buffer(buf);
|
||||
+ this->status = DEMUX_FINISHED;
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ if (remaining_bytes > buf->max_size) {
|
||||
+ xprintf(this->xine, XINE_VERBOSITY_LOG,
|
||||
+ _("sequence header too big (%u bytes)!\n"), remaining_bytes);
|
||||
+ this->input->seek(this->input, remaining_bytes-buf->max_size, SEEK_CUR);
|
||||
+ }
|
||||
+ remaining_bytes = 0;
|
||||
+ }
|
||||
+ else {
|
||||
+ buf->pts = (int64_t) pts * 90;
|
||||
+ if (!preview)
|
||||
+ check_newpts(this, buf->pts, (tag_type == FLV_TAG_TYPE_VIDEO));
|
||||
|
||||
- buf->decoder_flags = buf_flags;
|
||||
- if (preview)
|
||||
- buf->decoder_flags |= BUF_FLAG_PREVIEW;
|
||||
- if (!remaining_bytes)
|
||||
- buf->decoder_flags |= BUF_FLAG_FRAME_END;
|
||||
+ if (remaining_bytes > buf->max_size)
|
||||
+ buf->size = buf->max_size;
|
||||
+ else
|
||||
+ buf->size = remaining_bytes;
|
||||
+ remaining_bytes -= buf->size;
|
||||
|
||||
- if (this->input->read(this->input, buf->content, buf->size) != buf->size) {
|
||||
- buf->free_buffer(buf);
|
||||
- this->status = DEMUX_FINISHED;
|
||||
- break;
|
||||
+ buf->decoder_flags = buf_flags;
|
||||
+ if (preview)
|
||||
+ buf->decoder_flags |= BUF_FLAG_PREVIEW;
|
||||
+ if (!remaining_bytes)
|
||||
+ buf->decoder_flags |= BUF_FLAG_FRAME_END;
|
||||
+
|
||||
+ if (this->input->read(this->input, buf->content, buf->size) != buf->size) {
|
||||
+ buf->free_buffer(buf);
|
||||
+ this->status = DEMUX_FINISHED;
|
||||
+ break;
|
||||
+ }
|
||||
}
|
||||
|
||||
fifo->put(fifo, buf);
|
||||
@@ -649,8 +740,8 @@ static void seek_flv_file(demux_flv_t *this, off_t see
|
||||
|
||||
lprintf(" seeking %s to %d...\n",
|
||||
do_rewind ? "backward" : "forward", seek_pts);
|
||||
-
|
||||
- if (seek_pts == 0) {
|
||||
+
|
||||
+ if (seek_pos == 0 && seek_pts == 0) {
|
||||
this->input->seek(this->input, this->start, SEEK_SET);
|
||||
this->cur_pts = 0;
|
||||
return;
|
||||
@@ -676,11 +767,9 @@ static void seek_flv_file(demux_flv_t *this, off_t see
|
||||
|
||||
this->input->seek(this->input, this->index[i].offset-4, SEEK_SET);
|
||||
this->cur_pts = this->index[i].pts;
|
||||
- return;
|
||||
}
|
||||
}
|
||||
-
|
||||
- if (seek_pos && this->videocodec && abs(seek_pts-this->cur_pts) > 300000) {
|
||||
+ else if (seek_pos && this->videocodec && abs(seek_pts-this->cur_pts) > 300000) {
|
||||
off_t pos, size;
|
||||
|
||||
pos = this->input->get_current_pos(this->input);
|
||||
@@ -715,49 +804,50 @@ static void seek_flv_file(demux_flv_t *this, off_t see
|
||||
|
||||
lprintf(" ...resync failed!\n");
|
||||
this->input->seek(this->input, pos, SEEK_SET);
|
||||
- return;
|
||||
}
|
||||
-
|
||||
- while (do_rewind ? (seek_pts < this->cur_pts) : (seek_pts > this->cur_pts)) {
|
||||
- unsigned char tag_type;
|
||||
- int data_size;
|
||||
- int ptag_size;
|
||||
+ else if (seek_pts) {
|
||||
+ while (do_rewind ? (seek_pts < this->cur_pts) : (seek_pts > this->cur_pts)) {
|
||||
+ unsigned char tag_type;
|
||||
+ int data_size;
|
||||
+ int ptag_size;
|
||||
|
||||
- if (next_tag)
|
||||
- this->input->seek(this->input, next_tag, SEEK_CUR);
|
||||
+ if (next_tag)
|
||||
+ this->input->seek(this->input, next_tag, SEEK_CUR);
|
||||
|
||||
- len = this->input->read(this->input, buffer, 16);
|
||||
- if (len != 16) {
|
||||
- len = (len < 0) ? 0 : len;
|
||||
- break;
|
||||
- }
|
||||
+ len = this->input->read(this->input, buffer, 16);
|
||||
+ if (len != 16) {
|
||||
+ len = (len < 0) ? 0 : len;
|
||||
+ break;
|
||||
+ }
|
||||
|
||||
- ptag_size = _X_BE_32(&buffer[0]);
|
||||
- tag_type = buffer[4];
|
||||
- data_size = _X_BE_24(&buffer[5]);
|
||||
- pts = _X_BE_24(&buffer[8]) | (buffer[11] << 24);
|
||||
+ ptag_size = _X_BE_32(&buffer[0]);
|
||||
+ tag_type = buffer[4];
|
||||
+ data_size = _X_BE_24(&buffer[5]);
|
||||
+ pts = _X_BE_24(&buffer[8]) | (buffer[11] << 24);
|
||||
|
||||
- if (do_rewind) {
|
||||
- if (!ptag_size) break; /* beginning of movie */
|
||||
- next_tag = -(ptag_size + 16 + 4);
|
||||
- }
|
||||
- else {
|
||||
- next_tag = data_size - 1;
|
||||
- }
|
||||
+ if (do_rewind) {
|
||||
+ if (!ptag_size)
|
||||
+ break; /* beginning of movie */
|
||||
+ next_tag = -(ptag_size + 16 + 4);
|
||||
+ }
|
||||
+ else {
|
||||
+ next_tag = data_size - 1;
|
||||
+ }
|
||||
|
||||
- if (this->flags & FLV_FLAG_HAS_VIDEO) {
|
||||
- /* sync to video key frame */
|
||||
- if (tag_type != FLV_TAG_TYPE_VIDEO || (buffer[15] >> 4) != 0x01)
|
||||
- continue;
|
||||
- lprintf(" video keyframe found at %d...\n", pts);
|
||||
+ if (this->flags & FLV_FLAG_HAS_VIDEO) {
|
||||
+ /* sync to video key frame */
|
||||
+ if (tag_type != FLV_TAG_TYPE_VIDEO || (buffer[15] >> 4) != 0x01)
|
||||
+ continue;
|
||||
+ lprintf(" video keyframe found at %d...\n", pts);
|
||||
+ }
|
||||
+ this->cur_pts = pts;
|
||||
}
|
||||
- this->cur_pts = pts;
|
||||
- }
|
||||
|
||||
- /* seek back to the beginning of the tag */
|
||||
- this->input->seek(this->input, -len, SEEK_CUR);
|
||||
+ /* seek back to the beginning of the tag */
|
||||
+ this->input->seek(this->input, -len, SEEK_CUR);
|
||||
|
||||
- lprintf( " seeked to %d.\n", pts);
|
||||
+ lprintf( " seeked to %d.\n", pts);
|
||||
+ }
|
||||
}
|
||||
|
||||
|
||||
@@ -807,8 +897,12 @@ static int demux_flv_seek (demux_plugin_t *this_gen,
|
||||
this->status = DEMUX_OK;
|
||||
|
||||
if (INPUT_IS_SEEKABLE(this->input)) {
|
||||
- if (start_pos && !start_time)
|
||||
- start_time = (int64_t) this->length * start_pos / 65535;
|
||||
+ if (start_pos && !start_time) {
|
||||
+ if (this->length)
|
||||
+ start_time = (int64_t) this->length * start_pos / 65535;
|
||||
+ else if (this->index)
|
||||
+ start_time = this->index[(int)(start_pos * (this->num_indices-1) / 65535)].pts;
|
||||
+ }
|
||||
|
||||
if (!this->length || start_time < this->length) {
|
||||
seek_flv_file(this, start_pos, start_time);
|
||||
@@ -875,12 +969,6 @@ static demux_plugin_t *open_plugin (demux_class_t *cla
|
||||
|
||||
switch (stream->content_detection_method) {
|
||||
case METHOD_BY_EXTENSION:
|
||||
- if (!_x_demux_check_extension(input->get_mrl(input), "flv")) {
|
||||
- free (this);
|
||||
- return NULL;
|
||||
- }
|
||||
-
|
||||
- /* falling through is intended */
|
||||
case METHOD_BY_CONTENT:
|
||||
case METHOD_EXPLICIT:
|
||||
if (!open_flv_file(this)) {
|
Loading…
Reference in New Issue
Block a user