Initial commit - from Precise source
[freerdp-ubuntu-pcb-backport.git] / channels / drdynvc / tsmf / ffmpeg / tsmf_ffmpeg.c
1 /**
2  * FreeRDP: A Remote Desktop Protocol client.
3  * Video Redirection Virtual Channel - FFmpeg Decoder
4  *
5  * Copyright 2010-2011 Vic Lee
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *     http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  */
19
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <string.h>
23 #include <freerdp/utils/memory.h>
24 #include <freerdp/utils/event.h>
25 #include <freerdp/plugins/tsmf.h>
26 #include <libavcodec/avcodec.h>
27
28 #include "tsmf_constants.h"
29 #include "tsmf_decoder.h"
30
31 /* Compatibility with older FFmpeg */
32 #if LIBAVUTIL_VERSION_MAJOR < 50
33 #define AVMEDIA_TYPE_VIDEO 0
34 #define AVMEDIA_TYPE_AUDIO 1
35 #endif
36
37 typedef struct _TSMFFFmpegDecoder
38 {
39         ITSMFDecoder iface;
40
41         int media_type;
42         enum CodecID codec_id;
43         AVCodecContext* codec_context;
44         AVCodec* codec;
45         AVFrame* frame;
46         int prepared;
47
48         uint8* decoded_data;
49         uint32 decoded_size;
50         uint32 decoded_size_max;
51 } TSMFFFmpegDecoder;
52
53 static boolean tsmf_ffmpeg_init_context(ITSMFDecoder* decoder)
54 {
55         TSMFFFmpegDecoder* mdecoder = (TSMFFFmpegDecoder*) decoder;
56
57         mdecoder->codec_context = avcodec_alloc_context();
58         if (!mdecoder->codec_context)
59         {
60                 DEBUG_WARN("avcodec_alloc_context failed.");
61                 return false;
62         }
63
64         return true;
65 }
66
67 static boolean tsmf_ffmpeg_init_video_stream(ITSMFDecoder* decoder, const TS_AM_MEDIA_TYPE* media_type)
68 {
69         TSMFFFmpegDecoder* mdecoder = (TSMFFFmpegDecoder*) decoder;
70
71         mdecoder->codec_context->width = media_type->Width;
72         mdecoder->codec_context->height = media_type->Height;
73         mdecoder->codec_context->bit_rate = media_type->BitRate;
74         mdecoder->codec_context->time_base.den = media_type->SamplesPerSecond.Numerator;
75         mdecoder->codec_context->time_base.num = media_type->SamplesPerSecond.Denominator;
76
77         mdecoder->frame = avcodec_alloc_frame();
78
79         return true;
80 }
81
82 static boolean tsmf_ffmpeg_init_audio_stream(ITSMFDecoder* decoder, const TS_AM_MEDIA_TYPE* media_type)
83 {
84         TSMFFFmpegDecoder* mdecoder = (TSMFFFmpegDecoder*) decoder;
85
86         mdecoder->codec_context->sample_rate = media_type->SamplesPerSecond.Numerator;
87         mdecoder->codec_context->bit_rate = media_type->BitRate;
88         mdecoder->codec_context->channels = media_type->Channels;
89         mdecoder->codec_context->block_align = media_type->BlockAlign;
90
91 #ifdef AV_CPU_FLAG_SSE2
92         mdecoder->codec_context->dsp_mask = AV_CPU_FLAG_SSE2 | AV_CPU_FLAG_MMX2;
93 #else
94 #if LIBAVCODEC_VERSION_MAJOR < 53
95         mdecoder->codec_context->dsp_mask = FF_MM_SSE2 | FF_MM_MMXEXT;
96 #else
97         mdecoder->codec_context->dsp_mask = FF_MM_SSE2 | FF_MM_MMX2;
98 #endif
99 #endif
100
101         return true;
102 }
103
104 static boolean tsmf_ffmpeg_init_stream(ITSMFDecoder* decoder, const TS_AM_MEDIA_TYPE* media_type)
105 {
106         TSMFFFmpegDecoder* mdecoder = (TSMFFFmpegDecoder*) decoder;
107         uint32 size;
108         const uint8* s;
109         uint8* p;
110
111         mdecoder->codec = avcodec_find_decoder(mdecoder->codec_id);
112         if (!mdecoder->codec)
113         {
114                 DEBUG_WARN("avcodec_find_decoder failed.");
115                 return false;
116         }
117
118         mdecoder->codec_context->codec_id = mdecoder->codec_id;
119         mdecoder->codec_context->codec_type = mdecoder->media_type;
120
121         if (mdecoder->media_type == AVMEDIA_TYPE_VIDEO)
122         {
123                 if (!tsmf_ffmpeg_init_video_stream(decoder, media_type))
124                         return false;
125         }
126         else if (mdecoder->media_type == AVMEDIA_TYPE_AUDIO)
127         {
128                 if (!tsmf_ffmpeg_init_audio_stream(decoder, media_type))
129                         return false;
130         }
131
132         if (media_type->ExtraData)
133         {
134                 if (media_type->SubType == TSMF_SUB_TYPE_AVC1 &&
135                         media_type->FormatType == TSMF_FORMAT_TYPE_MPEG2VIDEOINFO)
136                 {
137                         /* The extradata format that FFmpeg uses is following CodecPrivate in Matroska.
138                            See http://haali.su/mkv/codecs.pdf */
139                         mdecoder->codec_context->extradata_size = media_type->ExtraDataSize + 8;
140                         mdecoder->codec_context->extradata = xzalloc(mdecoder->codec_context->extradata_size);
141                         p = mdecoder->codec_context->extradata;
142                         *p++ = 1; /* Reserved? */
143                         *p++ = media_type->ExtraData[8]; /* Profile */
144                         *p++ = 0; /* Profile */
145                         *p++ = media_type->ExtraData[12]; /* Level */
146                         *p++ = 0xff; /* Flag? */
147                         *p++ = 0xe0 | 0x01; /* Reserved | #sps */
148                         s = media_type->ExtraData + 20;
149                         size = ((uint32)(*s)) * 256 + ((uint32)(*(s + 1)));
150                         memcpy(p, s, size + 2);
151                         s += size + 2;
152                         p += size + 2;
153                         *p++ = 1; /* #pps */
154                         size = ((uint32)(*s)) * 256 + ((uint32)(*(s + 1)));
155                         memcpy(p, s, size + 2);
156                 }
157                 else
158                 {
159                         /* Add a padding to avoid invalid memory read in some codec */
160                         mdecoder->codec_context->extradata_size = media_type->ExtraDataSize + 8;
161                         mdecoder->codec_context->extradata = xzalloc(mdecoder->codec_context->extradata_size);
162                         memcpy(mdecoder->codec_context->extradata, media_type->ExtraData, media_type->ExtraDataSize);
163                         memset(mdecoder->codec_context->extradata + media_type->ExtraDataSize, 0, 8);
164                 }
165         }
166
167         if (mdecoder->codec->capabilities & CODEC_CAP_TRUNCATED)
168                 mdecoder->codec_context->flags |= CODEC_FLAG_TRUNCATED;
169
170         return true;
171 }
172
173 static boolean tsmf_ffmpeg_prepare(ITSMFDecoder* decoder)
174 {
175         TSMFFFmpegDecoder* mdecoder = (TSMFFFmpegDecoder*) decoder;
176
177         if (avcodec_open(mdecoder->codec_context, mdecoder->codec) < 0)
178         {
179                 DEBUG_WARN("avcodec_open failed.");
180                 return false;
181         }
182
183         mdecoder->prepared = 1;
184
185         return true;
186 }
187
188 static boolean tsmf_ffmpeg_set_format(ITSMFDecoder* decoder, TS_AM_MEDIA_TYPE* media_type)
189 {
190         TSMFFFmpegDecoder* mdecoder = (TSMFFFmpegDecoder*) decoder;
191
192         switch (media_type->MajorType)
193         {
194                 case TSMF_MAJOR_TYPE_VIDEO:
195                         mdecoder->media_type = AVMEDIA_TYPE_VIDEO;
196                         break;
197                 case TSMF_MAJOR_TYPE_AUDIO:
198                         mdecoder->media_type = AVMEDIA_TYPE_AUDIO;
199                         break;
200                 default:
201                         return false;
202         }
203         switch (media_type->SubType)
204         {
205                 case TSMF_SUB_TYPE_WVC1:
206                         mdecoder->codec_id = CODEC_ID_VC1;
207                         break;
208                 case TSMF_SUB_TYPE_WMA2:
209                         mdecoder->codec_id = CODEC_ID_WMAV2;
210                         break;
211                 case TSMF_SUB_TYPE_WMA9:
212                         mdecoder->codec_id = CODEC_ID_WMAPRO;
213                         break;
214                 case TSMF_SUB_TYPE_MP3:
215                         mdecoder->codec_id = CODEC_ID_MP3;
216                         break;
217                 case TSMF_SUB_TYPE_MP2A:
218                         mdecoder->codec_id = CODEC_ID_MP2;
219                         break;
220                 case TSMF_SUB_TYPE_MP2V:
221                         mdecoder->codec_id = CODEC_ID_MPEG2VIDEO;
222                         break;
223                 case TSMF_SUB_TYPE_WMV3:
224                         mdecoder->codec_id = CODEC_ID_WMV3;
225                         break;
226                 case TSMF_SUB_TYPE_AAC:
227                         mdecoder->codec_id = CODEC_ID_AAC;
228                         /* For AAC the pFormat is a HEAACWAVEINFO struct, and the codec data
229                            is at the end of it. See
230                            http://msdn.microsoft.com/en-us/library/dd757806.aspx */
231                         if (media_type->ExtraData)
232                         {
233                                 media_type->ExtraData += 12;
234                                 media_type->ExtraDataSize -= 12;
235                         }
236                         break;
237                 case TSMF_SUB_TYPE_H264:
238                 case TSMF_SUB_TYPE_AVC1:
239                         mdecoder->codec_id = CODEC_ID_H264;
240                         break;
241                 case TSMF_SUB_TYPE_AC3:
242                         mdecoder->codec_id = CODEC_ID_AC3;
243                         break;
244                 default:
245                         return false;
246         }
247
248         if (!tsmf_ffmpeg_init_context(decoder))
249                 return false;
250         if (!tsmf_ffmpeg_init_stream(decoder, media_type))
251                 return false;
252         if (!tsmf_ffmpeg_prepare(decoder))
253                 return false;
254
255         return true;
256 }
257
258 static boolean tsmf_ffmpeg_decode_video(ITSMFDecoder* decoder, const uint8* data, uint32 data_size, uint32 extensions)
259 {
260         TSMFFFmpegDecoder* mdecoder = (TSMFFFmpegDecoder*) decoder;
261         int decoded;
262         int len;
263         AVFrame* frame;
264         boolean ret = true;
265
266 #if LIBAVCODEC_VERSION_MAJOR < 52 || (LIBAVCODEC_VERSION_MAJOR == 52 && LIBAVCODEC_VERSION_MINOR <= 20)
267         len = avcodec_decode_video(mdecoder->codec_context, mdecoder->frame, &decoded, data, data_size);
268 #else
269         {
270                 AVPacket pkt;
271                 av_init_packet(&pkt);
272                 pkt.data = (uint8*) data;
273                 pkt.size = data_size;
274                 if (extensions & TSMM_SAMPLE_EXT_CLEANPOINT)
275                         pkt.flags |= AV_PKT_FLAG_KEY;
276                 len = avcodec_decode_video2(mdecoder->codec_context, mdecoder->frame, &decoded, &pkt);
277         }
278 #endif
279
280         if (len < 0)
281         {
282                 DEBUG_WARN("data_size %d, avcodec_decode_video failed (%d)", data_size, len);
283                 ret = false;
284         }
285         else if (!decoded)
286         {
287                 DEBUG_WARN("data_size %d, no frame is decoded.", data_size);
288                 ret = false;
289         }
290         else
291         {
292                 DEBUG_DVC("linesize[0] %d linesize[1] %d linesize[2] %d linesize[3] %d "
293                         "pix_fmt %d width %d height %d",
294                         mdecoder->frame->linesize[0], mdecoder->frame->linesize[1],
295                         mdecoder->frame->linesize[2], mdecoder->frame->linesize[3],
296                         mdecoder->codec_context->pix_fmt,
297                         mdecoder->codec_context->width, mdecoder->codec_context->height);
298
299                 mdecoder->decoded_size = avpicture_get_size(mdecoder->codec_context->pix_fmt,
300                         mdecoder->codec_context->width, mdecoder->codec_context->height);
301                 mdecoder->decoded_data = xzalloc(mdecoder->decoded_size);
302                 frame = avcodec_alloc_frame();
303                 avpicture_fill((AVPicture *) frame, mdecoder->decoded_data,
304                         mdecoder->codec_context->pix_fmt,
305                         mdecoder->codec_context->width, mdecoder->codec_context->height);
306
307                 av_picture_copy((AVPicture *) frame, (AVPicture *) mdecoder->frame,
308                         mdecoder->codec_context->pix_fmt,
309                         mdecoder->codec_context->width, mdecoder->codec_context->height);
310
311                 av_free(frame);
312         }
313
314         return ret;
315 }
316
317 static boolean tsmf_ffmpeg_decode_audio(ITSMFDecoder* decoder, const uint8* data, uint32 data_size, uint32 extensions)
318 {
319         TSMFFFmpegDecoder* mdecoder = (TSMFFFmpegDecoder*) decoder;
320         int len;
321         int frame_size;
322         uint32 src_size;
323         const uint8* src;
324         uint8* dst;
325         int dst_offset;
326
327 #if 0
328         LLOGLN(0, ("tsmf_ffmpeg_decode_audio: data_size %d", data_size));
329         int i;
330         for (i = 0; i < data_size; i++)
331         {
332                 LLOG(0, ("%02X ", data[i]));
333                 if (i % 16 == 15)
334                         LLOG(0, ("\n"));
335         }
336         LLOG(0, ("\n"));
337 #endif
338
339         if (mdecoder->decoded_size_max == 0)
340                 mdecoder->decoded_size_max = AVCODEC_MAX_AUDIO_FRAME_SIZE + 16;
341         mdecoder->decoded_data = xzalloc(mdecoder->decoded_size_max);
342         /* align the memory for SSE2 needs */
343         dst = (uint8*) (((uintptr_t)mdecoder->decoded_data + 15) & ~ 0x0F);
344         dst_offset = dst - mdecoder->decoded_data;
345         src = data;
346         src_size = data_size;
347
348         while (src_size > 0)
349         {
350                 /* Ensure enough space for decoding */
351                 if (mdecoder->decoded_size_max - mdecoder->decoded_size < AVCODEC_MAX_AUDIO_FRAME_SIZE)
352                 {
353                         mdecoder->decoded_size_max = mdecoder->decoded_size_max * 2 + 16;
354                         mdecoder->decoded_data = xrealloc(mdecoder->decoded_data, mdecoder->decoded_size_max);
355                         dst = (uint8*) (((uintptr_t)mdecoder->decoded_data + 15) & ~ 0x0F);
356                         if (dst - mdecoder->decoded_data != dst_offset)
357                         {
358                                 /* re-align the memory if the alignment has changed after realloc */
359                                 memmove(dst, mdecoder->decoded_data + dst_offset, mdecoder->decoded_size);
360                                 dst_offset = dst - mdecoder->decoded_data;
361                         }
362                         dst += mdecoder->decoded_size;
363                 }
364                 frame_size = mdecoder->decoded_size_max - mdecoder->decoded_size;
365 #if LIBAVCODEC_VERSION_MAJOR < 52 || (LIBAVCODEC_VERSION_MAJOR == 52 && LIBAVCODEC_VERSION_MINOR <= 20)
366                 len = avcodec_decode_audio2(mdecoder->codec_context,
367                         (int16_t*) dst, &frame_size,
368                         src, src_size);
369 #else
370                 {
371                         AVPacket pkt;
372                         av_init_packet(&pkt);
373                         pkt.data = (uint8*) src;
374                         pkt.size = src_size;
375                         len = avcodec_decode_audio3(mdecoder->codec_context,
376                                 (int16_t*) dst, &frame_size, &pkt);
377                 }
378 #endif
379                 if (len <= 0 || frame_size <= 0)
380                 {
381                         DEBUG_WARN("error decoding");
382                         break;
383                 }
384                 src += len;
385                 src_size -= len;
386                 mdecoder->decoded_size += frame_size;
387                 dst += frame_size;
388         }
389
390         if (mdecoder->decoded_size == 0)
391         {
392                 xfree(mdecoder->decoded_data);
393                 mdecoder->decoded_data = NULL;
394         }
395         else if (dst_offset)
396         {
397                 /* move the aligned decoded data to original place */
398                 memmove(mdecoder->decoded_data, mdecoder->decoded_data + dst_offset, mdecoder->decoded_size);
399         }
400
401         DEBUG_DVC("data_size %d decoded_size %d",
402                 data_size, mdecoder->decoded_size);
403
404         return true;
405 }
406
407 static boolean tsmf_ffmpeg_decode(ITSMFDecoder* decoder, const uint8* data, uint32 data_size, uint32 extensions)
408 {
409         TSMFFFmpegDecoder* mdecoder = (TSMFFFmpegDecoder*) decoder;
410
411         if (mdecoder->decoded_data)
412         {
413                 xfree(mdecoder->decoded_data);
414                 mdecoder->decoded_data = NULL;
415         }
416         mdecoder->decoded_size = 0;
417
418         switch (mdecoder->media_type)
419         {
420                 case AVMEDIA_TYPE_VIDEO:
421                         return tsmf_ffmpeg_decode_video(decoder, data, data_size, extensions);
422                 case AVMEDIA_TYPE_AUDIO:
423                         return tsmf_ffmpeg_decode_audio(decoder, data, data_size, extensions);
424                 default:
425                         DEBUG_WARN("unknown media type.");
426                         return false;
427         }
428 }
429
430 static uint8* tsmf_ffmpeg_get_decoded_data(ITSMFDecoder* decoder, uint32* size)
431 {
432         TSMFFFmpegDecoder* mdecoder = (TSMFFFmpegDecoder*) decoder;
433         uint8* buf;
434
435         *size = mdecoder->decoded_size;
436         buf = mdecoder->decoded_data;
437         mdecoder->decoded_data = NULL;
438         mdecoder->decoded_size = 0;
439         return buf;
440 }
441
442 static uint32 tsmf_ffmpeg_get_decoded_format(ITSMFDecoder* decoder)
443 {
444         TSMFFFmpegDecoder* mdecoder = (TSMFFFmpegDecoder*) decoder;
445
446         switch (mdecoder->codec_context->pix_fmt)
447         {
448                 case PIX_FMT_YUV420P:
449                         return RDP_PIXFMT_I420;
450
451                 default:
452                         DEBUG_WARN("unsupported pixel format %u",
453                                 mdecoder->codec_context->pix_fmt);
454                         return (uint32) -1;
455         }
456 }
457
458 static boolean tsmf_ffmpeg_get_decoded_dimension(ITSMFDecoder* decoder, uint32* width, uint32* height)
459 {
460         TSMFFFmpegDecoder* mdecoder = (TSMFFFmpegDecoder*) decoder;
461
462         if (mdecoder->codec_context->width > 0 && mdecoder->codec_context->height > 0)
463         {
464                 *width = mdecoder->codec_context->width;
465                 *height = mdecoder->codec_context->height;
466                 return true;
467         }
468         else
469         {
470                 return false;
471         }
472 }
473
474 static void tsmf_ffmpeg_free(ITSMFDecoder* decoder)
475 {
476         TSMFFFmpegDecoder* mdecoder = (TSMFFFmpegDecoder*) decoder;
477
478         if (mdecoder->frame)
479                 av_free(mdecoder->frame);
480         if (mdecoder->decoded_data)
481                 xfree(mdecoder->decoded_data);
482         if (mdecoder->codec_context)
483         {
484                 if (mdecoder->prepared)
485                         avcodec_close(mdecoder->codec_context);
486                 if (mdecoder->codec_context->extradata)
487                         xfree(mdecoder->codec_context->extradata);
488                 av_free(mdecoder->codec_context);
489         }
490         xfree(decoder);
491 }
492
493 static boolean initialized = false;
494
495 ITSMFDecoder*
496 TSMFDecoderEntry(void)
497 {
498         TSMFFFmpegDecoder * decoder;
499
500         if (!initialized)
501         {
502                 avcodec_init();
503                 avcodec_register_all();
504                 initialized = true;
505         }
506
507         decoder = xnew(TSMFFFmpegDecoder);
508
509         decoder->iface.SetFormat = tsmf_ffmpeg_set_format;
510         decoder->iface.Decode = tsmf_ffmpeg_decode;
511         decoder->iface.GetDecodedData = tsmf_ffmpeg_get_decoded_data;
512         decoder->iface.GetDecodedFormat = tsmf_ffmpeg_get_decoded_format;
513         decoder->iface.GetDecodedDimension = tsmf_ffmpeg_get_decoded_dimension;
514         decoder->iface.Free = tsmf_ffmpeg_free;
515
516         return (ITSMFDecoder*) decoder;
517 }
518