From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winedmo/main.c | 14 ++++++++++++++ dlls/winedmo/unix_demuxer.c | 6 ++++++ dlls/winedmo/unixlib.h | 10 ++++++++++ 3 files changed, 30 insertions(+)
diff --git a/dlls/winedmo/main.c b/dlls/winedmo/main.c index 7536566fe75..dc9829f25b2 100644 --- a/dlls/winedmo/main.c +++ b/dlls/winedmo/main.c @@ -133,12 +133,26 @@ static void buffer_lock( DMO_OUTPUT_DATA_BUFFER *buffer, struct sample *sample )
static void buffer_unlock( DMO_OUTPUT_DATA_BUFFER *buffer, struct sample *sample ) { + IMFSample *object; HRESULT hr;
if (FAILED(hr = IMediaBuffer_SetLength( buffer->pBuffer, sample->size ))) ERR( "Failed to update buffer length, hr %#lx\n", hr );
buffer->dwStatus = 0; + if (SUCCEEDED(hr = IMediaBuffer_QueryInterface( buffer->pBuffer, &IID_IMFSample, (void **)&object ))) + { + if (sample->dts != INT64_MIN) IMFSample_SetUINT64( object, &MFSampleExtension_DecodeTimestamp, sample->dts ); + if (sample->pts != INT64_MIN) IMFSample_SetSampleTime( object, sample->pts ); + if (sample->duration != INT64_MIN) IMFSample_SetSampleDuration( object, sample->duration ); + if (sample->flags & SAMPLE_FLAG_SYNC_POINT) IMFSample_SetUINT32( object, &MFSampleExtension_CleanPoint, 1 ); + IMFSample_Release( object ); + } + + if ((buffer->rtTimestamp = sample->pts) != INT64_MIN) buffer->dwStatus |= DMO_OUTPUT_DATA_BUFFERF_TIME; + if ((buffer->rtTimelength = sample->duration) != INT64_MIN) buffer->dwStatus |= DMO_OUTPUT_DATA_BUFFERF_TIMELENGTH; + if (sample->flags & SAMPLE_FLAG_SYNC_POINT) buffer->dwStatus |= DMO_OUTPUT_DATA_BUFFERF_SYNCPOINT; + if (sample->flags & SAMPLE_FLAG_INCOMPLETE) buffer->dwStatus |= DMO_OUTPUT_DATA_BUFFERF_INCOMPLETE; }
diff --git a/dlls/winedmo/unix_demuxer.c b/dlls/winedmo/unix_demuxer.c index d3e804aa6eb..50be8688397 100644 --- a/dlls/winedmo/unix_demuxer.c +++ b/dlls/winedmo/unix_demuxer.c @@ -165,6 +165,7 @@ NTSTATUS demuxer_read( void *arg ) AVFormatContext *ctx = get_demuxer( params->demuxer ); struct sample *sample = ¶ms->sample; UINT capacity = params->sample.size; + AVStream *stream; AVPacket *packet; int ret;
@@ -189,6 +190,11 @@ NTSTATUS demuxer_read( void *arg ) return STATUS_BUFFER_TOO_SMALL; }
+ stream = ctx->streams[packet->stream_index]; + sample->pts = get_stream_time( stream, packet->pts ); + sample->dts = get_stream_time( stream, packet->dts ); + sample->duration = get_stream_time( stream, packet->duration ); + if (packet->flags & AV_PKT_FLAG_KEY) sample->flags |= SAMPLE_FLAG_SYNC_POINT; memcpy( (void *)(UINT_PTR)sample->data, packet->data, packet->size ); params->stream = packet->stream_index; av_packet_free( &packet ); diff --git a/dlls/winedmo/unixlib.h b/dlls/winedmo/unixlib.h index 4e3fef9fa82..cf37bd5342a 100644 --- a/dlls/winedmo/unixlib.h +++ b/dlls/winedmo/unixlib.h @@ -64,8 +64,18 @@ struct read_callback_params };
+enum sample_flag +{ + SAMPLE_FLAG_SYNC_POINT = 1, + SAMPLE_FLAG_INCOMPLETE = 2, +}; + struct sample { + UINT32 flags; + INT64 dts; + INT64 pts; + UINT64 duration; UINT64 size; UINT64 data; /* pointer to user memory */ };