xref: /haiku/src/kits/media/MediaTrack.cpp (revision 9eb55bc1d104b8fda80898f8b25c94d8000c8255)
1 /***********************************************************************
2  * AUTHOR: Marcus Overhagen
3  *   FILE: MediaTrack.cpp
4  *  DESCR:
5  ***********************************************************************/
6 #include <MediaTrack.h>
7 #include <string.h>
8 #include "MediaExtractor.h"
9 #include "PluginManager.h"
10 #include "ReaderPlugin.h"
11 #include "debug.h"
12 
13 /*************************************************************
14  * protected BMediaTrack
15  *************************************************************/
16 
17 BMediaTrack::~BMediaTrack()
18 {
19 	CALLED();
20 	if (fDecoder)
21 		_DestroyDecoder(fDecoder);
22 }
23 
24 /*************************************************************
25  * public BMediaTrack
26  *************************************************************/
27 
28 status_t
29 BMediaTrack::InitCheck() const
30 {
31 	CALLED();
32 	return fErr;
33 }
34 
35 
36 status_t
37 BMediaTrack::GetCodecInfo(media_codec_info *mci) const
38 {
39 	CALLED();
40 	if (!fDecoder)
41 		return B_NO_INIT;
42 
43 	*mci = fMCI;
44 
45 	return B_OK;
46 }
47 
48 
49 status_t
50 BMediaTrack::EncodedFormat(media_format *out_format) const
51 {
52 	CALLED();
53 	if (!out_format)
54 		return B_BAD_VALUE;
55 	if (!fExtractor)
56 		return B_NO_INIT;
57 
58 	*out_format = *fExtractor->EncodedFormat(fStream);
59 
60 	return B_OK;
61 }
62 
63 
64 status_t
65 BMediaTrack::DecodedFormat(media_format *inout_format)
66 {
67 	CALLED();
68 	if (!inout_format)
69 		return B_BAD_VALUE;
70 	if (!fExtractor || !fDecoder)
71 		return B_NO_INIT;
72 
73 	return fDecoder->NegotiateOutputFormat(inout_format);
74 }
75 
76 
77 int64
78 BMediaTrack::CountFrames() const
79 {
80 	CALLED();
81 	return fExtractor ? fExtractor->CountFrames(fStream) : 0;
82 }
83 
84 
85 bigtime_t
86 BMediaTrack::Duration() const
87 {
88 	CALLED();
89 	return fExtractor ? fExtractor->Duration(fStream) : 0;
90 }
91 
92 
93 int64
94 BMediaTrack::CurrentFrame() const
95 {
96 	return fCurFrame;
97 }
98 
99 
100 bigtime_t
101 BMediaTrack::CurrentTime() const
102 {
103 	return fCurTime;
104 }
105 
106 
107 status_t
108 BMediaTrack::ReadFrames(void *out_buffer,
109 						int64 *out_frameCount,
110 						media_header *mh)
111 {
112 	return ReadFrames(out_buffer, out_frameCount, mh, 0);
113 }
114 
115 
116 status_t
117 BMediaTrack::ReadFrames(void *out_buffer,
118 						int64 *out_frameCount,
119 						media_header *mh /* = 0 */,
120 						media_decode_info *info /* = 0 */)
121 {
122 //	CALLED();
123 	if (!fDecoder)
124 		return B_NO_INIT;
125 	if (!out_buffer || !out_frameCount)
126 		return B_BAD_VALUE;
127 
128 	status_t result;
129 
130 	media_header temp_header;
131 	if (!mh)
132 		mh = &temp_header;
133 	else
134 		memset(mh, 0, sizeof(*mh)); // clear it first, as the decoder doesn't set all fields
135 
136 	result = fDecoder->Decode(out_buffer, out_frameCount, mh, info);
137 	if (result == B_OK) {
138 		fCurFrame += *out_frameCount;
139 		fCurTime = mh->start_time;
140 	} else {
141 		printf("BMediaTrack::ReadFrames: decoder returned error 0x%08lx (%s)\n", result, strerror(result));
142 		*out_frameCount = 0;
143 	}
144 	return result;
145 }
146 
147 
148 status_t
149 BMediaTrack::ReplaceFrames(const void *in_buffer,
150 						   int64 *io_frameCount,
151 						   const media_header *mh)
152 {
153 	UNIMPLEMENTED();
154 
155 	return B_OK;
156 }
157 
158 
159 status_t
160 BMediaTrack::SeekToTime(bigtime_t *inout_time,
161 						int32 flags)
162 {
163 	CALLED();
164 	if (!fDecoder || !fExtractor)
165 		return B_NO_INIT;
166 	if (!inout_time)
167 		return B_BAD_VALUE;
168 
169 	status_t result;
170 	uint32 seekTo;
171 	bigtime_t seekTime;
172 
173 	int64 frame;
174 	bigtime_t time;
175 
176 	seekTo = (flags & B_MEDIA_SEEK_DIRECTION_MASK) | B_MEDIA_SEEK_TO_TIME;
177 	seekTime = *inout_time;
178 
179 	time = seekTime;
180 	result = fExtractor->Seek(fStream, seekTo, &frame, &time);
181 	if (result != B_OK) {
182 		printf("BMediaTrack::SeekToTime: extractor seek failed\n");
183 		return result;
184 	}
185 
186 	result = fDecoder->Seek(seekTo, 0, &frame, seekTime, &time);
187 	if (result != B_OK) {
188 		printf("BMediaTrack::SeekToTime: decoder seek failed\n");
189 		return result;
190 	}
191 
192 	*inout_time = time;
193 	fCurFrame = frame;
194 	fCurTime = time;
195 
196 	printf("BMediaTrack::SeekToTime finished, requested %.6f, result %.6f\n", seekTime / 1000000.0, *inout_time / 1000000.0);
197 
198 	return B_OK;
199 }
200 
201 
202 status_t
203 BMediaTrack::SeekToFrame(int64 *inout_frame,
204 						 int32 flags)
205 {
206 	CALLED();
207 	if (!fDecoder || !fExtractor)
208 		return B_NO_INIT;
209 	if (!inout_frame)
210 		return B_BAD_VALUE;
211 
212 	status_t result;
213 	uint32 seekTo;
214 	int64 seekFrame;
215 
216 	int64 frame;
217 	bigtime_t time;
218 
219 	seekTo = (flags & B_MEDIA_SEEK_DIRECTION_MASK) | B_MEDIA_SEEK_TO_FRAME;
220 	seekFrame = *inout_frame;
221 
222 	frame = seekFrame;
223 	result = fExtractor->Seek(fStream, seekTo, &frame, &time);
224 	if (result != B_OK) {
225 		printf("BMediaTrack::SeekToFrame: extractor seek failed\n");
226 		return result;
227 	}
228 
229 	result = fDecoder->Seek(seekTo, seekFrame, &frame, 0, &time);
230 	if (result != B_OK) {
231 		return result;
232 		printf("BMediaTrack::SeekToFrame: decoder seek failed\n");
233 	}
234 
235 	*inout_frame = frame;
236 	fCurFrame = frame;
237 	fCurTime = time;
238 
239 	printf("BMediaTrack::SeekToTime SeekToFrame, requested %Ld, result %Ld\n", seekFrame, *inout_frame);
240 
241 	return B_OK;
242 }
243 
244 
245 status_t
246 BMediaTrack::FindKeyFrameForTime(bigtime_t *inout_time,
247 								 int32 flags) const
248 {
249 	UNIMPLEMENTED();
250 
251 	return B_OK;
252 }
253 
254 
255 status_t
256 BMediaTrack::FindKeyFrameForFrame(int64 *inout_frame,
257 								  int32 flags) const
258 {
259 	UNIMPLEMENTED();
260 
261 	return B_OK;
262 }
263 
264 
265 status_t
266 BMediaTrack::ReadChunk(char **out_buffer,
267 					   int32 *out_size,
268 					   media_header *mh /* = 0 */)
269 {
270 	CALLED();
271 	if (!fExtractor)
272 		return B_NO_INIT;
273 	if (!out_buffer || !out_size)
274 		return B_BAD_VALUE;
275 
276 	status_t result;
277 	media_header temp_header;
278 	if (!mh)
279 		mh = &temp_header;
280 
281 	result = fExtractor->GetNextChunk(fStream, (void **)out_buffer, out_size, mh);
282 
283 	fCurTime = mh->start_time;
284 
285 	return result;
286 }
287 
288 
289 status_t
290 BMediaTrack::AddCopyright(const char *data)
291 {
292 	UNIMPLEMENTED();
293 
294 	return B_OK;
295 }
296 
297 
298 status_t
299 BMediaTrack::AddTrackInfo(uint32 code,
300 						  const void *data,
301 						  size_t size,
302 						  uint32 flags)
303 {
304 	UNIMPLEMENTED();
305 
306 	return B_OK;
307 }
308 
309 
310 status_t
311 BMediaTrack::WriteFrames(const void *data,
312 						 int32 num_frames,
313 						 int32 flags)
314 {
315 	UNIMPLEMENTED();
316 
317 	return B_OK;
318 }
319 
320 
321 status_t
322 BMediaTrack::WriteFrames(const void *data,
323 						 int64 num_frames,
324 						 media_encode_info *info)
325 {
326 	UNIMPLEMENTED();
327 
328 	return B_OK;
329 }
330 
331 
332 status_t
333 BMediaTrack::WriteChunk(const void *data,
334 						size_t size,
335 						uint32 flags)
336 {
337 	UNIMPLEMENTED();
338 
339 	return B_OK;
340 }
341 
342 
343 status_t
344 BMediaTrack::WriteChunk(const void *data,
345 						size_t size,
346 						media_encode_info *info)
347 {
348 	UNIMPLEMENTED();
349 
350 	return B_OK;
351 }
352 
353 
354 status_t
355 BMediaTrack::Flush()
356 {
357 	UNIMPLEMENTED();
358 
359 	return B_OK;
360 }
361 
362 
363 BParameterWeb *
364 BMediaTrack::Web()
365 {
366 	UNIMPLEMENTED();
367 	return NULL;
368 }
369 
370 
371 status_t
372 BMediaTrack::GetParameterValue(int32 id,
373 							   void *valu,
374 							   size_t *size)
375 {
376 	UNIMPLEMENTED();
377 
378 	return B_ERROR;
379 }
380 
381 
382 status_t
383 BMediaTrack::SetParameterValue(int32 id,
384 							   const void *valu,
385 							   size_t size)
386 {
387 	UNIMPLEMENTED();
388 
389 	return B_ERROR;
390 }
391 
392 
393 BView *
394 BMediaTrack::GetParameterView()
395 {
396 	UNIMPLEMENTED();
397 	return NULL;
398 }
399 
400 
401 status_t
402 BMediaTrack::GetQuality(float *quality)
403 {
404 	UNIMPLEMENTED();
405 
406 	return B_ERROR;
407 }
408 
409 
410 status_t
411 BMediaTrack::SetQuality(float quality)
412 {
413 	UNIMPLEMENTED();
414 
415 	return B_ERROR;
416 }
417 
418 
419 status_t
420 BMediaTrack::GetEncodeParameters(encode_parameters *parameters) const
421 {
422 	UNIMPLEMENTED();
423 
424 	return B_ERROR;
425 }
426 
427 
428 status_t
429 BMediaTrack::SetEncodeParameters(encode_parameters *parameters)
430 {
431 	UNIMPLEMENTED();
432 
433 	return B_ERROR;
434 }
435 
436 
437 status_t
438 BMediaTrack::Perform(int32 selector,
439 					 void *data)
440 {
441 	UNIMPLEMENTED();
442 
443 	return B_ERROR;
444 }
445 
446 /*************************************************************
447  * private BMediaTrack
448  *************************************************************/
449 
450 BMediaTrack::BMediaTrack(BPrivate::media::MediaExtractor *extractor,
451 						 int32 stream)
452 {
453 	CALLED();
454 	fExtractor = extractor;
455 	fStream = stream;
456 	fErr = B_OK;
457 
458 	if (fExtractor->CreateDecoder(fStream, &fDecoder, &fMCI) != B_OK) {
459 		// we do not set fErr here, because ReadChunk should still work
460 		fDecoder = 0;
461 		return;
462 	}
463 
464 	fCurFrame = 0;
465 	fCurTime = 0;
466 
467 	// not used:
468 	fEncoder = 0;
469 	fEncoderID = 0;
470 	fWriter = 0;
471 }
472 
473 
474 BMediaTrack::BMediaTrack(BPrivate::MediaWriter *writer,
475 						 int32 stream_num,
476 						 media_format *in_format,
477 						 BPrivate::media::Encoder *encoder,
478 						 media_codec_info *mci)
479 {
480 	UNIMPLEMENTED();
481 }
482 
483 /*
484 // unimplemented
485 BMediaTrack::BMediaTrack()
486 BMediaTrack::BMediaTrack(const BMediaTrack &)
487 BMediaTrack &BMediaTrack::operator=(const BMediaTrack &)
488 */
489 
490 status_t BMediaTrack::_Reserved_BMediaTrack_0(int32 arg, ...) { return B_ERROR; }
491 status_t BMediaTrack::_Reserved_BMediaTrack_1(int32 arg, ...) { return B_ERROR; }
492 status_t BMediaTrack::_Reserved_BMediaTrack_2(int32 arg, ...) { return B_ERROR; }
493 status_t BMediaTrack::_Reserved_BMediaTrack_3(int32 arg, ...) { return B_ERROR; }
494 status_t BMediaTrack::_Reserved_BMediaTrack_4(int32 arg, ...) { return B_ERROR; }
495 status_t BMediaTrack::_Reserved_BMediaTrack_5(int32 arg, ...) { return B_ERROR; }
496 status_t BMediaTrack::_Reserved_BMediaTrack_6(int32 arg, ...) { return B_ERROR; }
497 status_t BMediaTrack::_Reserved_BMediaTrack_7(int32 arg, ...) { return B_ERROR; }
498 status_t BMediaTrack::_Reserved_BMediaTrack_8(int32 arg, ...) { return B_ERROR; }
499 status_t BMediaTrack::_Reserved_BMediaTrack_9(int32 arg, ...) { return B_ERROR; }
500 status_t BMediaTrack::_Reserved_BMediaTrack_10(int32 arg, ...) { return B_ERROR; }
501 status_t BMediaTrack::_Reserved_BMediaTrack_11(int32 arg, ...) { return B_ERROR; }
502 status_t BMediaTrack::_Reserved_BMediaTrack_12(int32 arg, ...) { return B_ERROR; }
503 status_t BMediaTrack::_Reserved_BMediaTrack_13(int32 arg, ...) { return B_ERROR; }
504 status_t BMediaTrack::_Reserved_BMediaTrack_14(int32 arg, ...) { return B_ERROR; }
505 status_t BMediaTrack::_Reserved_BMediaTrack_15(int32 arg, ...) { return B_ERROR; }
506 status_t BMediaTrack::_Reserved_BMediaTrack_16(int32 arg, ...) { return B_ERROR; }
507 status_t BMediaTrack::_Reserved_BMediaTrack_17(int32 arg, ...) { return B_ERROR; }
508 status_t BMediaTrack::_Reserved_BMediaTrack_18(int32 arg, ...) { return B_ERROR; }
509 status_t BMediaTrack::_Reserved_BMediaTrack_19(int32 arg, ...) { return B_ERROR; }
510 status_t BMediaTrack::_Reserved_BMediaTrack_20(int32 arg, ...) { return B_ERROR; }
511 status_t BMediaTrack::_Reserved_BMediaTrack_21(int32 arg, ...) { return B_ERROR; }
512 status_t BMediaTrack::_Reserved_BMediaTrack_22(int32 arg, ...) { return B_ERROR; }
513 status_t BMediaTrack::_Reserved_BMediaTrack_23(int32 arg, ...) { return B_ERROR; }
514 status_t BMediaTrack::_Reserved_BMediaTrack_24(int32 arg, ...) { return B_ERROR; }
515 status_t BMediaTrack::_Reserved_BMediaTrack_25(int32 arg, ...) { return B_ERROR; }
516 status_t BMediaTrack::_Reserved_BMediaTrack_26(int32 arg, ...) { return B_ERROR; }
517 status_t BMediaTrack::_Reserved_BMediaTrack_27(int32 arg, ...) { return B_ERROR; }
518 status_t BMediaTrack::_Reserved_BMediaTrack_28(int32 arg, ...) { return B_ERROR; }
519 status_t BMediaTrack::_Reserved_BMediaTrack_29(int32 arg, ...) { return B_ERROR; }
520 status_t BMediaTrack::_Reserved_BMediaTrack_30(int32 arg, ...) { return B_ERROR; }
521 status_t BMediaTrack::_Reserved_BMediaTrack_31(int32 arg, ...) { return B_ERROR; }
522 status_t BMediaTrack::_Reserved_BMediaTrack_32(int32 arg, ...) { return B_ERROR; }
523 status_t BMediaTrack::_Reserved_BMediaTrack_33(int32 arg, ...) { return B_ERROR; }
524 status_t BMediaTrack::_Reserved_BMediaTrack_34(int32 arg, ...) { return B_ERROR; }
525 status_t BMediaTrack::_Reserved_BMediaTrack_35(int32 arg, ...) { return B_ERROR; }
526 status_t BMediaTrack::_Reserved_BMediaTrack_36(int32 arg, ...) { return B_ERROR; }
527 status_t BMediaTrack::_Reserved_BMediaTrack_37(int32 arg, ...) { return B_ERROR; }
528 status_t BMediaTrack::_Reserved_BMediaTrack_38(int32 arg, ...) { return B_ERROR; }
529 status_t BMediaTrack::_Reserved_BMediaTrack_39(int32 arg, ...) { return B_ERROR; }
530 status_t BMediaTrack::_Reserved_BMediaTrack_40(int32 arg, ...) { return B_ERROR; }
531 status_t BMediaTrack::_Reserved_BMediaTrack_41(int32 arg, ...) { return B_ERROR; }
532 status_t BMediaTrack::_Reserved_BMediaTrack_42(int32 arg, ...) { return B_ERROR; }
533 status_t BMediaTrack::_Reserved_BMediaTrack_43(int32 arg, ...) { return B_ERROR; }
534 status_t BMediaTrack::_Reserved_BMediaTrack_44(int32 arg, ...) { return B_ERROR; }
535 status_t BMediaTrack::_Reserved_BMediaTrack_45(int32 arg, ...) { return B_ERROR; }
536 status_t BMediaTrack::_Reserved_BMediaTrack_46(int32 arg, ...) { return B_ERROR; }
537 status_t BMediaTrack::_Reserved_BMediaTrack_47(int32 arg, ...) { return B_ERROR; }
538 
539