1b2859abeSMarcus Overhagen/*
2b2859abeSMarcus Overhagen * Copyright (c) 2004-2007 Marcus Overhagen <marcus@overhagen.de>
3b2859abeSMarcus Overhagen *
4b2859abeSMarcus Overhagen * Permission is hereby granted, free of charge, to any person
5b2859abeSMarcus Overhagen * obtaining a copy of this software and associated documentation
6b2859abeSMarcus Overhagen * files (the "Software"), to deal in the Software without restriction,
7b2859abeSMarcus Overhagen * including without limitation the rights to use, copy, modify,
8b2859abeSMarcus Overhagen * merge, publish, distribute, sublicense, and/or sell copies of
9b2859abeSMarcus Overhagen * the Software, and to permit persons to whom the Software is
10b2859abeSMarcus Overhagen * furnished to do so, subject to the following conditions:
11b2859abeSMarcus Overhagen *
12b2859abeSMarcus Overhagen * The above copyright notice and this permission notice shall be
13b2859abeSMarcus Overhagen * included in all copies or substantial portions of the Software.
14b2859abeSMarcus Overhagen *
15b2859abeSMarcus Overhagen * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16b2859abeSMarcus Overhagen * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
17b2859abeSMarcus Overhagen * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18b2859abeSMarcus Overhagen * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
19b2859abeSMarcus Overhagen * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
20b2859abeSMarcus Overhagen * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21b2859abeSMarcus Overhagen * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22b2859abeSMarcus Overhagen * OTHER DEALINGS IN THE SOFTWARE.
23b2859abeSMarcus Overhagen */
24b2859abeSMarcus Overhagen
25b289aaf6SAxel Dörfler
26b2859abeSMarcus Overhagen#include <fcntl.h>
27b2859abeSMarcus Overhagen#include <malloc.h>
28b2859abeSMarcus Overhagen#include <math.h>
29b2859abeSMarcus Overhagen#include <stdio.h>
30b2859abeSMarcus Overhagen#include <stdlib.h>
31b2859abeSMarcus Overhagen#include <string.h>
32b2859abeSMarcus Overhagen#include <sys/uio.h>
33b2859abeSMarcus Overhagen#include <unistd.h>
34b2859abeSMarcus Overhagen
35b2859abeSMarcus Overhagen#include <MediaRoster.h>
36b2859abeSMarcus Overhagen#include <Buffer.h>
37b2859abeSMarcus Overhagen#include <BufferGroup.h>
38b2859abeSMarcus Overhagen#include <ParameterWeb.h>
39b2859abeSMarcus Overhagen#include <TimeSource.h>
40b2859abeSMarcus Overhagen#include <String.h>
41b2859abeSMarcus Overhagen#include <Autolock.h>
42b2859abeSMarcus Overhagen#include <Debug.h>
43b2859abeSMarcus Overhagen
44b2859abeSMarcus Overhagen#include <Directory.h>
45b2859abeSMarcus Overhagen#include <Entry.h>
46b2859abeSMarcus Overhagen#include <Path.h>
47b2859abeSMarcus Overhagen
48fcb9bdc0SMarcus Overhagen#include "MediaFormat.h"
49fcb9bdc0SMarcus Overhagen#include "Packet.h"
50fcb9bdc0SMarcus Overhagen#include "PacketQueue.h"
51fcb9bdc0SMarcus Overhagen#include "pes.h"
52b2859abeSMarcus Overhagen#include "config.h"
53b2859abeSMarcus Overhagen
54b2859abeSMarcus Overhagen//#define DUMP_VIDEO
55b2859abeSMarcus Overhagen//#define DUMP_AUDIO
56b2859abeSMarcus Overhagen//#define DUMP_RAW_AUDIO
5775a6d51eSColin Günther//#define DUMP_MPEG_TS
58b2859abeSMarcus Overhagen
59b2859abeSMarcus Overhagen
60b2859abeSMarcus Overhagen#include "DVBMediaNode.h"
61b2859abeSMarcus Overhagen
62b2859abeSMarcus Overhagen#define ENABLE_TRACE
63b2859abeSMarcus Overhagen//#define ENABLE_TRACE_TIMING
64b2859abeSMarcus Overhagen
65b2859abeSMarcus Overhagen#undef TRACE
66b2859abeSMarcus Overhagen
67b2859abeSMarcus Overhagen#ifdef ENABLE_TRACE
68b2859abeSMarcus Overhagen	#define TRACE printf
69b2859abeSMarcus Overhagen#else
70b2859abeSMarcus Overhagen	#define TRACE(a...)
71b2859abeSMarcus Overhagen#endif
72b2859abeSMarcus Overhagen
73b2859abeSMarcus Overhagen#ifdef ENABLE_TRACE_TIMING
74b2859abeSMarcus Overhagen	#define TRACE_TIMING printf
75b2859abeSMarcus Overhagen#else
76b2859abeSMarcus Overhagen	#define TRACE_TIMING(a...)
77b2859abeSMarcus Overhagen#endif
78b2859abeSMarcus Overhagen
79b2859abeSMarcus Overhagen#define RETURN_IF_ERROR(expr) { status_t e = (expr); if (e != B_OK) return e; }
80b2859abeSMarcus Overhagen
81b2859abeSMarcus Overhagen#define ID_RAW_VIDEO	0
82b2859abeSMarcus Overhagen#define ID_RAW_AUDIO	1
83b2859abeSMarcus Overhagen#define ID_ENC_VIDEO	2
84b2859abeSMarcus Overhagen#define ID_ENC_AUDIO	3
85b2859abeSMarcus Overhagen#define ID_TS			4
86b2859abeSMarcus Overhagen
87b2859abeSMarcus Overhagen// Timeouts for requesting buffers, if the system is busy,
88b2859abeSMarcus Overhagen// the output buffer queue is full, requesting a buffer will
89b2859abeSMarcus Overhagen// timeout, and we need to drop the current data
90b2859abeSMarcus Overhagen#define VIDEO_BUFFER_REQUEST_TIMEOUT	20000
91b2859abeSMarcus Overhagen#define AUDIO_BUFFER_REQUEST_TIMEOUT	10000
92b2859abeSMarcus Overhagen
93b2859abeSMarcus Overhagen// DVB data arrives early and with a timestamp, this is used to validate
94b2859abeSMarcus Overhagen// that the timestamp is correct and we don't get stuck
9538738909SColin Günther#define VIDEO_MAX_EARLY					3000000
9638738909SColin Günther	// up to 3 seconds too early
9738738909SColin Günther#define VIDEO_MAX_LATE					50000
9838738909SColin Günther	// no more than 50 ms too late
9938738909SColin Günther#define AUDIO_MAX_EARLY					3000000
10038738909SColin Günther	// up to 3 seconds too early
10138738909SColin Günther#define AUDIO_MAX_LATE					50000
10238738909SColin Günther	// no more than 50 ms too late
10338738909SColin Günther
10438738909SColin Günther#define PROCESSING_LATENCY				1500
10538738909SColin Günther	// assumed latency for sending the buffer
106b2859abeSMarcus Overhagen
107b2859abeSMarcus Overhagen#define STOP_CAPTURE_WHILE_TUNING		1
108b2859abeSMarcus Overhagen
109b2859abeSMarcus Overhagen#define M_REFRESH_PARAMETER_WEB 		(BTimedEventQueue::B_USER_EVENT + 1)
110b2859abeSMarcus Overhagen
111b2859abeSMarcus Overhagen
112b2859abeSMarcus OverhagenDVBMediaNode::DVBMediaNode(
113b2859abeSMarcus Overhagen	BMediaAddOn *addon, const char *name,
114fcb9bdc0SMarcus Overhagen	int32 internal_id, DVBCard *card)
115b2859abeSMarcus Overhagen :	BMediaNode(name)
116b2859abeSMarcus Overhagen ,	BBufferProducer(B_MEDIA_RAW_VIDEO)
117b2859abeSMarcus Overhagen ,	BControllable()
118fcb9bdc0SMarcus Overhagen ,	BMediaEventLooper()
119b2859abeSMarcus Overhagen ,	fStopDisabled(false)
120b2859abeSMarcus Overhagen ,	fOutputEnabledRawVideo(false)
121b2859abeSMarcus Overhagen ,	fOutputEnabledRawAudio(false)
122b2859abeSMarcus Overhagen ,	fOutputEnabledEncVideo(false)
123b2859abeSMarcus Overhagen ,	fOutputEnabledEncAudio(false)
124b2859abeSMarcus Overhagen ,	fOutputEnabledTS(false)
125b2859abeSMarcus Overhagen ,	fCardDataQueue(new PacketQueue(6))
126b2859abeSMarcus Overhagen ,	fRawVideoQueue(new PacketQueue(56))
127b2859abeSMarcus Overhagen ,	fRawAudioQueue(new PacketQueue(56))
128b2859abeSMarcus Overhagen ,	fEncVideoQueue(new PacketQueue(56))
129b2859abeSMarcus Overhagen ,	fEncAudioQueue(new PacketQueue(56))
130b2859abeSMarcus Overhagen ,	fMpegTsQueue(new PacketQueue(16))
131b2859abeSMarcus Overhagen ,	fCard(card)
132b2859abeSMarcus Overhagen ,	fCaptureThreadsActive(false)
133b2859abeSMarcus Overhagen ,	fThreadIdCardReader(-1)
134b2859abeSMarcus Overhagen ,	fThreadIdMpegDemux(-1)
135b2859abeSMarcus Overhagen ,	fThreadIdRawAudio(-1)
136b2859abeSMarcus Overhagen ,	fThreadIdRawVideo(-1)
137b2859abeSMarcus Overhagen ,	fThreadIdEncAudio(-1)
138b2859abeSMarcus Overhagen ,	fThreadIdEncVideo(-1)
139b2859abeSMarcus Overhagen ,	fThreadIdMpegTS(-1)
140b2859abeSMarcus Overhagen ,	fTerminateThreads(false)
141293ccd77SStephan Aßmus ,	fDemux(new TransportStreamDemux(fRawVideoQueue, fRawAudioQueue,
142293ccd77SStephan Aßmus 		fEncVideoQueue, fEncAudioQueue, fMpegTsQueue))
143b2859abeSMarcus Overhagen ,	fBufferGroupRawVideo(0)
144b2859abeSMarcus Overhagen ,	fBufferGroupRawAudio(0)
145b2859abeSMarcus Overhagen ,	fInterfaceType(DVB_TYPE_UNKNOWN)
146b2859abeSMarcus Overhagen ,	fAudioPid(-1)
147b2859abeSMarcus Overhagen ,	fVideoPid(-1)
148b2859abeSMarcus Overhagen ,	fPcrPid(-1)
149b2859abeSMarcus Overhagen ,	fTuningSuccess(false)
150b2859abeSMarcus Overhagen ,	fCaptureActive(false)
151b2859abeSMarcus Overhagen ,	fVideoDelaySem(create_sem(0, "video delay sem"))
152b2859abeSMarcus Overhagen ,	fAudioDelaySem(create_sem(0, "audio delay sem"))
153b2859abeSMarcus Overhagen ,	fSelectedState(-1)
154b2859abeSMarcus Overhagen ,	fSelectedRegion(-1)
155b2859abeSMarcus Overhagen ,	fSelectedChannel(-1)
156b2859abeSMarcus Overhagen ,	fSelectedAudio(-1)
157b2859abeSMarcus Overhagen ,	fStateList(new StringList)
158b2859abeSMarcus Overhagen ,	fRegionList(new StringList)
159b2859abeSMarcus Overhagen ,	fChannelList(new StringList)
160b2859abeSMarcus Overhagen ,	fAudioList(new StringList)
161b2859abeSMarcus Overhagen ,	fVideoDecoder(0)
162b2859abeSMarcus Overhagen ,	fAudioDecoder(0)
163b2859abeSMarcus Overhagen ,	fCurrentVideoPacket(0)
164b2859abeSMarcus Overhagen ,	fCurrentAudioPacket(0)
165b2859abeSMarcus Overhagen{
166b2859abeSMarcus Overhagen	TRACE("DVBMediaNode::DVBMediaNode\n");
167b2859abeSMarcus Overhagen
168b2859abeSMarcus Overhagen	AddNodeKind(B_PHYSICAL_INPUT);
169b2859abeSMarcus Overhagen
170b2859abeSMarcus Overhagen	fInternalID = internal_id;
171b2859abeSMarcus Overhagen	fAddOn = addon;
172b2859abeSMarcus Overhagen
173b2859abeSMarcus Overhagen	fInitStatus = B_OK;
174b2859abeSMarcus Overhagen
175b2859abeSMarcus Overhagen	InitDefaultFormats();
176b2859abeSMarcus Overhagen
177b2859abeSMarcus Overhagen	// in the beginning, the required formats are the same as the defaults
178b2859abeSMarcus Overhagen	fRequiredFormatRawVideo = fDefaultFormatRawVideo;
179b2859abeSMarcus Overhagen	fRequiredFormatRawAudio = fDefaultFormatRawAudio;
180b2859abeSMarcus Overhagen	fRequiredFormatEncVideo = fDefaultFormatEncVideo;
181b2859abeSMarcus Overhagen	fRequiredFormatEncAudio = fDefaultFormatEncAudio;
182b2859abeSMarcus Overhagen	fRequiredFormatTS = fDefaultFormatTS;
183b2859abeSMarcus Overhagen
184b2859abeSMarcus Overhagen	TRACE("current RunMode = %d\n", RunMode());
185b2859abeSMarcus Overhagen
186b2859abeSMarcus Overhagen#ifdef DUMP_VIDEO
187b2859abeSMarcus Overhagen	fVideoFile = open("/boot/home/dvb-video.mpg", O_RDWR | O_CREAT | O_TRUNC);
188b2859abeSMarcus Overhagen#endif
189b2859abeSMarcus Overhagen#ifdef DUMP_AUDIO
190b2859abeSMarcus Overhagen	fAudioFile = open("/boot/home/dvb-audio.mpg", O_RDWR | O_CREAT | O_TRUNC);
191b2859abeSMarcus Overhagen#endif
192b2859abeSMarcus Overhagen#ifdef DUMP_RAW_AUDIO
19338738909SColin Günther	fRawAudioFile = open("/boot/home/dvb-audio.raw",
19438738909SColin Günther		O_RDWR | O_CREAT | O_TRUNC);
195b2859abeSMarcus Overhagen#endif
19675a6d51eSColin Günther#ifdef DUMP_MPEG_TS
19775a6d51eSColin Günther	fMpegTsFile = open("/boot/home/dvb-mpeg.ts", O_RDWR | O_CREAT | O_TRUNC);
19875a6d51eSColin Günther#endif
199b2859abeSMarcus Overhagen}
200b2859abeSMarcus Overhagen
201b2859abeSMarcus Overhagen
202b2859abeSMarcus OverhagenDVBMediaNode::~DVBMediaNode()
203b2859abeSMarcus Overhagen{
204b2859abeSMarcus Overhagen	TRACE("DVBMediaNode::~DVBMediaNode\n");
205b2859abeSMarcus Overhagen
206b2859abeSMarcus Overhagen	StopCapture();
207b2859abeSMarcus Overhagen
208b2859abeSMarcus Overhagen	delete_sem(fVideoDelaySem);
209b2859abeSMarcus Overhagen	delete_sem(fAudioDelaySem);
210b2859abeSMarcus Overhagen
211b2859abeSMarcus Overhagen	// fCard is owned by the media addon
212b2859abeSMarcus Overhagen	delete fCardDataQueue;
213b2859abeSMarcus Overhagen	delete fRawVideoQueue;
214b2859abeSMarcus Overhagen	delete fRawAudioQueue;
215b2859abeSMarcus Overhagen	delete fEncVideoQueue;
216b2859abeSMarcus Overhagen	delete fEncAudioQueue;
217b2859abeSMarcus Overhagen	delete fMpegTsQueue;
218b2859abeSMarcus Overhagen
219b2859abeSMarcus Overhagen	delete fDemux;
220b2859abeSMarcus Overhagen
221b2859abeSMarcus Overhagen	delete fBufferGroupRawVideo;
222b2859abeSMarcus Overhagen	delete fBufferGroupRawAudio;
223b2859abeSMarcus Overhagen
224b2859abeSMarcus Overhagen	delete fStateList;
225b2859abeSMarcus Overhagen	delete fRegionList;
226b2859abeSMarcus Overhagen	delete fChannelList;
227b2859abeSMarcus Overhagen	delete fAudioList;
228b2859abeSMarcus Overhagen
229b2859abeSMarcus Overhagen#ifdef DUMP_VIDEO
230b2859abeSMarcus Overhagen	close(fVideoFile);
231b2859abeSMarcus Overhagen#endif
232b2859abeSMarcus Overhagen#ifdef DUMP_AUDIO
233b2859abeSMarcus Overhagen	close(fAudioFile);
234b2859abeSMarcus Overhagen#endif
235b2859abeSMarcus Overhagen#ifdef DUMP_RAW_AUDIO
236b2859abeSMarcus Overhagen	close(fRawAudioFile);
237b2859abeSMarcus Overhagen#endif
23875a6d51eSColin Günther#ifdef DUMP_MPEG_TS
23975a6d51eSColin Günther	close(fMpegTsFile);
24075a6d51eSColin Günther#endif
241b2859abeSMarcus Overhagen
242b2859abeSMarcus Overhagen}
243b2859abeSMarcus Overhagen
244b2859abeSMarcus Overhagen
245b2859abeSMarcus Overhagen/* BMediaNode */
246b2859abeSMarcus Overhagen
247b2859abeSMarcus Overhagen
248b2859abeSMarcus OverhagenBMediaAddOn *
249b2859abeSMarcus OverhagenDVBMediaNode::AddOn(int32 *internal_id) const
250b2859abeSMarcus Overhagen{
251b2859abeSMarcus Overhagen	if (internal_id)
252b2859abeSMarcus Overhagen		*internal_id = fInternalID;
253b2859abeSMarcus Overhagen	return fAddOn;
254b2859abeSMarcus Overhagen}
255b2859abeSMarcus Overhagen
256b2859abeSMarcus Overhagen
257b2859abeSMarcus Overhagenstatus_t
258b2859abeSMarcus OverhagenDVBMediaNode::HandleMessage(int32 message, const void *data, size_t size)
259b2859abeSMarcus Overhagen{
260b2859abeSMarcus Overhagen	return B_ERROR;
261b2859abeSMarcus Overhagen}
262b2859abeSMarcus Overhagen
263b2859abeSMarcus Overhagen
264b2859abeSMarcus Overhagenvoid
265b2859abeSMarcus OverhagenDVBMediaNode::Preroll()
266b2859abeSMarcus Overhagen{
267b2859abeSMarcus Overhagen	/* This hook may be called before the node is started to give the hardware
268b2859abeSMarcus Overhagen	 * a chance to start. */
269b2859abeSMarcus Overhagen}
270b2859abeSMarcus Overhagen
271b2859abeSMarcus Overhagen
272b2859abeSMarcus Overhagenvoid
273b2859abeSMarcus OverhagenDVBMediaNode::SetTimeSource(BTimeSource *time_source)
274b2859abeSMarcus Overhagen{
275b2859abeSMarcus Overhagen	TRACE("DVBMediaNode::SetTimeSource\n");
276b2859abeSMarcus Overhagen	//printf("current RunMode = %d\n", RunMode());
277b2859abeSMarcus Overhagen	//printf("_m_recordDelay = %Ld\n", _m_recordDelay);
278b2859abeSMarcus Overhagen}
279b2859abeSMarcus Overhagen
280b2859abeSMarcus Overhagen
281b2859abeSMarcus Overhagenvoid
282b2859abeSMarcus OverhagenDVBMediaNode::SetRunMode(run_mode mode)
283b2859abeSMarcus Overhagen{
284b2859abeSMarcus Overhagen	TRACE("DVBMediaNode::SetRunMode: %d\n", mode);
285b2859abeSMarcus Overhagen	TRACE("current RunMode = %d\n", RunMode());
286b2859abeSMarcus Overhagen	//printf("_m_recordDelay = %Ld\n", _m_recordDelay);
287b2859abeSMarcus Overhagen}
288b2859abeSMarcus Overhagen
289b2859abeSMarcus Overhagen
290b2859abeSMarcus Overhagen/* BMediaEventLooper */
291b2859abeSMarcus Overhagen
292b2859abeSMarcus Overhagen
293b2859abeSMarcus Overhagenvoid
294b2859abeSMarcus OverhagenDVBMediaNode::NodeRegistered()
295b2859abeSMarcus Overhagen{
296b2859abeSMarcus Overhagen	TRACE("DVBMediaNode::NodeRegistered\n");
297b2859abeSMarcus Overhagen
298b2859abeSMarcus Overhagen	fOutputRawVideo.node = Node();
299b2859abeSMarcus Overhagen	fOutputRawVideo.source.port = ControlPort();
300b2859abeSMarcus Overhagen	fOutputRawVideo.source.id = ID_RAW_VIDEO;
301b2859abeSMarcus Overhagen	fOutputRawVideo.destination = media_destination::null;
302b2859abeSMarcus Overhagen	fOutputRawVideo.format = fDefaultFormatRawVideo;
30338738909SColin Günther	strcpy(fOutputRawVideo.name, SourceDefaultName(fOutputRawVideo.source));
304b2859abeSMarcus Overhagen
305b2859abeSMarcus Overhagen	fOutputRawAudio.node = Node();
306b2859abeSMarcus Overhagen	fOutputRawAudio.source.port = ControlPort();
307b2859abeSMarcus Overhagen	fOutputRawAudio.source.id = ID_RAW_AUDIO;
308b2859abeSMarcus Overhagen	fOutputRawAudio.destination = media_destination::null;
309b2859abeSMarcus Overhagen	fOutputRawAudio.format = fDefaultFormatRawAudio;
31038738909SColin Günther	strcpy(fOutputRawAudio.name, SourceDefaultName(fOutputRawAudio.source));
311b2859abeSMarcus Overhagen
312b2859abeSMarcus Overhagen	fOutputEncVideo.node = Node();
313b2859abeSMarcus Overhagen	fOutputEncVideo.source.port = ControlPort();
314b2859abeSMarcus Overhagen	fOutputEncVideo.source.id = ID_ENC_VIDEO;
315b2859abeSMarcus Overhagen	fOutputEncVideo.destination = media_destination::null;
316b2859abeSMarcus Overhagen	fOutputEncVideo.format = fDefaultFormatEncVideo;
31738738909SColin Günther	strcpy(fOutputEncVideo.name, SourceDefaultName(fOutputEncVideo.source));
318b2859abeSMarcus Overhagen
319b2859abeSMarcus Overhagen	fOutputEncAudio.node = Node();
320b2859abeSMarcus Overhagen	fOutputEncAudio.source.port = ControlPort();
321b2859abeSMarcus Overhagen	fOutputEncAudio.source.id = ID_ENC_AUDIO;
322b2859abeSMarcus Overhagen	fOutputEncAudio.destination = media_destination::null;
323b2859abeSMarcus Overhagen	fOutputEncAudio.format = fDefaultFormatEncAudio;
32438738909SColin Günther	strcpy(fOutputEncAudio.name, SourceDefaultName(fOutputEncAudio.source));
325b2859abeSMarcus Overhagen
326b2859abeSMarcus Overhagen	fOutputTS.node = Node();
327b2859abeSMarcus Overhagen	fOutputTS.source.port = ControlPort();
328b2859abeSMarcus Overhagen	fOutputTS.source.id = ID_TS;
329b2859abeSMarcus Overhagen	fOutputTS.destination = media_destination::null;
330b2859abeSMarcus Overhagen	fOutputTS.format = fDefaultFormatTS;
33138738909SColin Günther	strcpy(fOutputTS.name, SourceDefaultName(fOutputTS.source));
332b2859abeSMarcus Overhagen
333b2859abeSMarcus Overhagen	fCard->GetCardType(&fInterfaceType);
334b2859abeSMarcus Overhagen
335b2859abeSMarcus Overhagen	// set control thread priority
336b2859abeSMarcus Overhagen	SetPriority(110);
337b2859abeSMarcus Overhagen
338b2859abeSMarcus Overhagen	LoadSettings();
339b2859abeSMarcus Overhagen
340b2859abeSMarcus Overhagen	RefreshParameterWeb();
341b2859abeSMarcus Overhagen
34238738909SColin Günther	// this nodes operates in recording mode, so set it (will be done
34338738909SColin Günther	// asynchronously)
344b2859abeSMarcus Overhagen	BMediaRoster::Roster()->SetRunModeNode(Node(), B_RECORDING);
34538738909SColin Günther		// as it's a notification hook, calling this doesn't work:
34638738909SColin Günther		// SetRunMode(B_RECORDING);
347b2859abeSMarcus Overhagen
348b2859abeSMarcus Overhagen	//printf("RunMode = %d\n", RunMode());
349b2859abeSMarcus Overhagen	//printf("_m_recordDelay = %Ld\n", _m_recordDelay);
3506d2f2ec1SDario Casalinuovo
3516d2f2ec1SDario Casalinuovo	Run();
352b2859abeSMarcus Overhagen}
353b2859abeSMarcus Overhagen
354b2859abeSMarcus Overhagen
355b2859abeSMarcus Overhagenvoid
356b2859abeSMarcus OverhagenDVBMediaNode::Stop(bigtime_t performance_time, bool immediate)
357b2859abeSMarcus Overhagen{
358b2859abeSMarcus Overhagen	if (fStopDisabled)
359b2859abeSMarcus Overhagen		return;
360b2859abeSMarcus Overhagen	else
361b2859abeSMarcus Overhagen		BMediaEventLooper::Stop(performance_time, immediate);
362b2859abeSMarcus Overhagen}
363b2859abeSMarcus Overhagen
364b2859abeSMarcus Overhagen
365b2859abeSMarcus Overhagenvoid
366b2859abeSMarcus OverhagenDVBMediaNode::HandleEvent(const media_timed_event *event,
367b2859abeSMarcus Overhagen		bigtime_t lateness, bool realTimeEvent)
368b2859abeSMarcus Overhagen{
369b2859abeSMarcus Overhagen
370b2859abeSMarcus Overhagen	switch(event->type)
371b2859abeSMarcus Overhagen	{
372b2859abeSMarcus Overhagen		case M_REFRESH_PARAMETER_WEB:
373b2859abeSMarcus Overhagen			RefreshParameterWeb();
374b2859abeSMarcus Overhagen			break;
375b2859abeSMarcus Overhagen		case BTimedEventQueue::B_START:
376b2859abeSMarcus Overhagen			HandleStart(event->event_time);
377b2859abeSMarcus Overhagen			break;
378b2859abeSMarcus Overhagen		case BTimedEventQueue::B_STOP:
379b2859abeSMarcus Overhagen			HandleStop();
380b2859abeSMarcus Overhagen			break;
381b2859abeSMarcus Overhagen		case BTimedEventQueue::B_WARP:
382b2859abeSMarcus Overhagen			HandleTimeWarp(event->bigdata);
383b2859abeSMarcus Overhagen			break;
384b2859abeSMarcus Overhagen		case BTimedEventQueue::B_SEEK:
385b2859abeSMarcus Overhagen			HandleSeek(event->bigdata);
386b2859abeSMarcus Overhagen			break;
387b2859abeSMarcus Overhagen		case BTimedEventQueue::B_HANDLE_BUFFER:
388b2859abeSMarcus Overhagen		case BTimedEventQueue::B_DATA_STATUS:
389b2859abeSMarcus Overhagen		case BTimedEventQueue::B_PARAMETER:
390b2859abeSMarcus Overhagen		default:
39138738909SColin Günther			TRACE("DVBMediaNode::HandleEvent: Unhandled event -- %lx\n",
39238738909SColin Günther				event->type);
393b2859abeSMarcus Overhagen			break;
394b2859abeSMarcus Overhagen	}
395b2859abeSMarcus Overhagen}
396b2859abeSMarcus Overhagen
397b2859abeSMarcus Overhagen
398b2859abeSMarcus Overhagen/* BBufferProducer */
399b2859abeSMarcus Overhagen
400b2859abeSMarcus Overhagen
401b2859abeSMarcus Overhagenstatus_t
402b2859abeSMarcus OverhagenDVBMediaNode::FormatChangeRequested(const media_source &source,
403b2859abeSMarcus Overhagen		const media_destination &destination, media_format *io_format,
404b2859abeSMarcus Overhagen		int32 *_deprecated_)
405b2859abeSMarcus Overhagen{
40638738909SColin Günther	TRACE("DVBMediaNode::FormatChangeRequested denied: %s\n",
40738738909SColin Günther		SourceDefaultName(source));
408b2859abeSMarcus Overhagen	return B_ERROR;
409b2859abeSMarcus Overhagen}
410b2859abeSMarcus Overhagen
411b2859abeSMarcus Overhagen
412b2859abeSMarcus Overhagenstatus_t
413b2859abeSMarcus OverhagenDVBMediaNode::GetNextOutput(int32 *cookie, media_output *out_output)
414b2859abeSMarcus Overhagen{
415b2859abeSMarcus Overhagen	switch (*cookie) {
416b2859abeSMarcus Overhagen		case 0: *out_output = fOutputRawVideo;	break;
417b2859abeSMarcus Overhagen		case 1: *out_output = fOutputRawAudio;	break;
418b2859abeSMarcus Overhagen		case 2: *out_output = fOutputEncVideo;	break;
419b2859abeSMarcus Overhagen		case 3: *out_output = fOutputEncAudio;	break;
420b2859abeSMarcus Overhagen		case 4: *out_output = fOutputTS;		break;
421b2859abeSMarcus Overhagen		default:								return B_BAD_INDEX;
422b2859abeSMarcus Overhagen	}
423b2859abeSMarcus Overhagen
424b2859abeSMarcus Overhagen	(*cookie) += 1;
425b2859abeSMarcus Overhagen	return B_OK;
426b2859abeSMarcus Overhagen}
427b2859abeSMarcus Overhagen
428b2859abeSMarcus Overhagen
429b2859abeSMarcus Overhagenstatus_t
430b2859abeSMarcus OverhagenDVBMediaNode::DisposeOutputCookie(int32 cookie)
431b2859abeSMarcus Overhagen{
432b2859abeSMarcus Overhagen	return B_OK;
433b2859abeSMarcus Overhagen}
434b2859abeSMarcus Overhagen
435b2859abeSMarcus Overhagen
436b2859abeSMarcus Overhagenstatus_t
437b2859abeSMarcus OverhagenDVBMediaNode::SetBufferGroup(const media_source &source, BBufferGroup *group)
438b2859abeSMarcus Overhagen{
43938738909SColin Günther	TRACE("DVBMediaNode::SetBufferGroup denied: %s\n",
44038738909SColin Günther		SourceDefaultName(source));
441b2859abeSMarcus Overhagen	return B_ERROR;
442b2859abeSMarcus Overhagen}
443b2859abeSMarcus Overhagen
444b2859abeSMarcus Overhagen
445b2859abeSMarcus Overhagenstatus_t
446b2859abeSMarcus OverhagenDVBMediaNode::VideoClippingChanged(const media_source &for_source,
447b2859abeSMarcus Overhagen		int16 num_shorts, int16 *clip_data,
448b2859abeSMarcus Overhagen		const media_video_display_info &display, int32 *_deprecated_)
449b2859abeSMarcus Overhagen{
450b2859abeSMarcus Overhagen	return B_ERROR;
451b2859abeSMarcus Overhagen}
452b2859abeSMarcus Overhagen
453b2859abeSMarcus Overhagen
454b2859abeSMarcus Overhagenstatus_t
455b2859abeSMarcus OverhagenDVBMediaNode::GetLatency(bigtime_t *out_latency)
456b2859abeSMarcus Overhagen{
457b2859abeSMarcus Overhagen	if (B_OK != BBufferProducer::GetLatency(out_latency))
458b2859abeSMarcus Overhagen		*out_latency = 50000;
459b2859abeSMarcus Overhagen
460b2859abeSMarcus Overhagen	printf("DVBMediaNode::GetLatency: %Ld\n", *out_latency);
461b2859abeSMarcus Overhagen	*out_latency += PROCESSING_LATENCY;
462b2859abeSMarcus Overhagen	return B_OK;
463b2859abeSMarcus Overhagen}
464b2859abeSMarcus Overhagen
465b2859abeSMarcus Overhagen
466b2859abeSMarcus Overhagenstatus_t
467b2859abeSMarcus OverhagenDVBMediaNode::FormatSuggestionRequested(
468b2859abeSMarcus Overhagen		media_type type, int32 quality, media_format *format)
469b2859abeSMarcus Overhagen{
470b2859abeSMarcus Overhagen	TRACE("DVBMediaNode::FormatSuggestionRequested\n");
471b2859abeSMarcus Overhagen
472b2859abeSMarcus Overhagen	switch (type) {
47338738909SColin Günther		case B_MEDIA_RAW_VIDEO:
47438738909SColin Günther			*format = fDefaultFormatRawVideo;
47538738909SColin Günther			break;
47638738909SColin Günther
47738738909SColin Günther		case B_MEDIA_RAW_AUDIO:
47838738909SColin Günther			*format = fDefaultFormatRawAudio;
47938738909SColin Günther			break;
48038738909SColin Günther
48138738909SColin Günther		case B_MEDIA_ENCODED_VIDEO:
48238738909SColin Günther			*format = fDefaultFormatEncVideo;
48338738909SColin Günther			break;
48438738909SColin Günther
48538738909SColin Günther		case B_MEDIA_ENCODED_AUDIO:
48638738909SColin Günther			*format = fDefaultFormatEncAudio;
48738738909SColin Günther			break;
48838738909SColin Günther
48938738909SColin Günther		case B_MEDIA_MULTISTREAM:
49038738909SColin Günther			*format = fDefaultFormatTS;
49138738909SColin Günther			break;
49238738909SColin Günther
49338738909SColin Günther		default:
49438738909SColin Günther			TRACE("Bad type!\n");
49538738909SColin Günther			return B_MEDIA_BAD_FORMAT;
496b2859abeSMarcus Overhagen	}
497b2859abeSMarcus Overhagen
498b2859abeSMarcus Overhagen	#ifdef DEBUG
499b2859abeSMarcus Overhagen		TRACE("suggested format: ");
500b2859abeSMarcus Overhagen		PrintFormat(*format);
501b2859abeSMarcus Overhagen	#endif
502b2859abeSMarcus Overhagen
503b2859abeSMarcus Overhagen	return B_OK;
504b2859abeSMarcus Overhagen}
505b2859abeSMarcus Overhagen
506b2859abeSMarcus Overhagen
507b2859abeSMarcus Overhagenstatus_t
508b2859abeSMarcus OverhagenDVBMediaNode::FormatProposal(const media_source &source, media_format *format)
509b2859abeSMarcus Overhagen{
510b2859abeSMarcus Overhagen	TRACE("DVBMediaNode::FormatProposal: %s\n", SourceDefaultName(source));
511b2859abeSMarcus Overhagen
512b2859abeSMarcus Overhagen	/* The connection process:
513b2859abeSMarcus Overhagen	 * we are here => BBufferProducer::FormatProposal
514b2859abeSMarcus Overhagen	 *                BBufferConsumer::AcceptFormat
515b2859abeSMarcus Overhagen	 *                BBufferProducer::PrepareToConnect
516b2859abeSMarcus Overhagen	 *                BBufferConsumer::Connected
517b2859abeSMarcus Overhagen	 *                BBufferProducer::Connect
518b2859abeSMarcus Overhagen	 *
519b2859abeSMarcus Overhagen	 * What we need to do:
520b2859abeSMarcus Overhagen	 * - if the format contains a wildcard AND we have a requirement for that
521b2859abeSMarcus Overhagen	 *   field, set it to the value we need.
522b2859abeSMarcus Overhagen	 * - if a field has a value that is not wildcard and not supported by us,
523b2859abeSMarcus Overhagen	 *   we don't change it, and return B_MEDIA_BAD_FORMAT
524b2859abeSMarcus Overhagen	 * - after we are done, the format may still contain wildcards.
525b2859abeSMarcus Overhagen	 */
526b2859abeSMarcus Overhagen
527b2859abeSMarcus Overhagen	if (source.port != ControlPort())
528b2859abeSMarcus Overhagen		goto _bad_source;
529b2859abeSMarcus Overhagen
530b2859abeSMarcus Overhagen	#ifdef DEBUG
531b2859abeSMarcus Overhagen		TRACE("proposed format: ");
532b2859abeSMarcus Overhagen		PrintFormat(*format);
533b2859abeSMarcus Overhagen		TRACE("required format: ");
534b2859abeSMarcus Overhagen		switch (source.id) {
53538738909SColin Günther			case ID_RAW_VIDEO:
53638738909SColin Günther				PrintFormat(fRequiredFormatRawVideo);
53738738909SColin Günther				break;
53838738909SColin Günther
53938738909SColin Günther			case ID_RAW_AUDIO:
54038738909SColin Günther				PrintFormat(fRequiredFormatRawAudio);
54138738909SColin Günther				break;
54238738909SColin Günther
54338738909SColin Günther			case ID_ENC_VIDEO:
54438738909SColin Günther				PrintFormat(fRequiredFormatEncVideo);
54538738909SColin Günther				break;
54638738909SColin Günther
54738738909SColin Günther			case ID_ENC_AUDIO:
54838738909SColin Günther				PrintFormat(fRequiredFormatEncAudio);
54938738909SColin Günther				break;
55038738909SColin Günther
55138738909SColin Günther			case ID_TS:
55238738909SColin Günther				PrintFormat(fRequiredFormatTS);
55338738909SColin Günther				break;
554b2859abeSMarcus Overhagen		}
555b2859abeSMarcus Overhagen	#endif
556b2859abeSMarcus Overhagen
557b2859abeSMarcus Overhagen	switch (source.id) {
558b2859abeSMarcus Overhagen		case ID_RAW_VIDEO:
559b2859abeSMarcus Overhagen			// check if destination still available
560b2859abeSMarcus Overhagen			if (fOutputRawVideo.destination != media_destination::null)
561b2859abeSMarcus Overhagen				goto _bad_source;
562b2859abeSMarcus Overhagen			// set requirements and check if compatible
563b2859abeSMarcus Overhagen			color_space c;
564b2859abeSMarcus Overhagen			c = format->u.raw_video.display.format;
565b2859abeSMarcus Overhagen			format->SpecializeTo(&fRequiredFormatRawVideo);
566b2859abeSMarcus Overhagen			format->u.raw_video.display.format = c;
567b2859abeSMarcus Overhagen//			if (!format->Matches(&fRequiredFormatRawVideo))
568b2859abeSMarcus Overhagen//				goto _bad_format_1;
569b2859abeSMarcus Overhagen			if (!VerifyFormatRawVideo(format->u.raw_video))
570b2859abeSMarcus Overhagen				goto _bad_format_2;
571b2859abeSMarcus Overhagen			break;
572b2859abeSMarcus Overhagen
573b2859abeSMarcus Overhagen		case ID_RAW_AUDIO:
574b2859abeSMarcus Overhagen			// check if destination still available
575b2859abeSMarcus Overhagen			if (fOutputRawAudio.destination != media_destination::null)
576b2859abeSMarcus Overhagen				goto _bad_source;
577b2859abeSMarcus Overhagen			// set requirements and check if compatible
578b2859abeSMarcus Overhagen			format->SpecializeTo(&fRequiredFormatRawAudio);
579b2859abeSMarcus Overhagen			if (!format->Matches(&fRequiredFormatRawAudio))
580b2859abeSMarcus Overhagen				goto _bad_format_1;
581b2859abeSMarcus Overhagen			if (!VerifyFormatRawAudio(format->u.raw_audio))
582b2859abeSMarcus Overhagen				goto _bad_format_2;
583b2859abeSMarcus Overhagen			break;
584b2859abeSMarcus Overhagen
585b2859abeSMarcus Overhagen		case ID_ENC_VIDEO:
586b2859abeSMarcus Overhagen			// check if destination still available
587b2859abeSMarcus Overhagen			if (fOutputEncVideo.destination != media_destination::null)
588b2859abeSMarcus Overhagen				goto _bad_source;
589b2859abeSMarcus Overhagen			// set requirements and check if compatible
590b2859abeSMarcus Overhagen			format->SpecializeTo(&fRequiredFormatEncVideo);
591b2859abeSMarcus Overhagen			if (!format->Matches(&fRequiredFormatEncVideo))
592b2859abeSMarcus Overhagen				goto _bad_format_1;
593b2859abeSMarcus Overhagen			break;
594b2859abeSMarcus Overhagen
595b2859abeSMarcus Overhagen		case ID_ENC_AUDIO:
596b2859abeSMarcus Overhagen			// check if destination still available
597b2859abeSMarcus Overhagen			if (fOutputEncAudio.destination != media_destination::null)
598b2859abeSMarcus Overhagen				goto _bad_source;
599b2859abeSMarcus Overhagen			// set requirements and check if compatible
600b2859abeSMarcus Overhagen			format->SpecializeTo(&fRequiredFormatEncAudio);
601b2859abeSMarcus Overhagen			if (!format->Matches(&fRequiredFormatEncAudio))
602b2859abeSMarcus Overhagen				goto _bad_format_1;
603b2859abeSMarcus Overhagen			break;
604b2859abeSMarcus Overhagen
605b2859abeSMarcus Overhagen		case ID_TS:
606b2859abeSMarcus Overhagen			// check if destination still available
607b2859abeSMarcus Overhagen			if (fOutputTS.destination != media_destination::null)
608b2859abeSMarcus Overhagen				goto _bad_source;
609b2859abeSMarcus Overhagen			// set requirements and check if compatible
610b2859abeSMarcus Overhagen			format->SpecializeTo(&fRequiredFormatTS);
611b2859abeSMarcus Overhagen			if (!format->Matches(&fRequiredFormatTS))
612b2859abeSMarcus Overhagen				goto _bad_format_1;
613b2859abeSMarcus Overhagen			break;
614b2859abeSMarcus Overhagen
615b2859abeSMarcus Overhagen		default:
616b2859abeSMarcus Overhagen			goto _bad_source;
617b2859abeSMarcus Overhagen	}
618b2859abeSMarcus Overhagen
619b2859abeSMarcus Overhagen	#ifdef DEBUG
620b2859abeSMarcus Overhagen		TRACE("final format: ");
621b2859abeSMarcus Overhagen		PrintFormat(*format);
622b2859abeSMarcus Overhagen	#endif
623b2859abeSMarcus Overhagen
624b2859abeSMarcus Overhagen	return B_OK;
625b2859abeSMarcus Overhagen
626b2859abeSMarcus Overhagen_bad_source:
627b2859abeSMarcus Overhagen	TRACE("Error: bad source!\n");
628b2859abeSMarcus Overhagen	return B_MEDIA_BAD_SOURCE;
629b2859abeSMarcus Overhagen
630b2859abeSMarcus Overhagen_bad_format_1:
631b2859abeSMarcus Overhagen	TRACE("Error, bad format (1): ");
632b2859abeSMarcus Overhagen	goto _bad_format;
633b2859abeSMarcus Overhagen
634b2859abeSMarcus Overhagen_bad_format_2:
635b2859abeSMarcus Overhagen	TRACE("Error, bad format (2): ");
636b2859abeSMarcus Overhagen	goto _bad_format;
637b2859abeSMarcus Overhagen
638b2859abeSMarcus Overhagen_bad_format:
639b2859abeSMarcus Overhagen	#ifdef DEBUG
640b2859abeSMarcus Overhagen		PrintFormat(*format);
641b2859abeSMarcus Overhagen	#endif
642b2859abeSMarcus Overhagen	return B_MEDIA_BAD_FORMAT;
643b2859abeSMarcus Overhagen}
644b2859abeSMarcus Overhagen
645b2859abeSMarcus Overhagen
646b2859abeSMarcus Overhagenstatus_t
647b2859abeSMarcus OverhagenDVBMediaNode::PrepareToConnect(const media_source &source,
648b2859abeSMarcus Overhagen		const media_destination &destination, media_format *format,
649b2859abeSMarcus Overhagen		media_source *out_source, char *out_name)
650b2859abeSMarcus Overhagen{
651b2859abeSMarcus Overhagen	/* The connection process:
652b2859abeSMarcus Overhagen	 *                BBufferProducer::FormatProposal
653b2859abeSMarcus Overhagen	 *                BBufferConsumer::AcceptFormat
654b2859abeSMarcus Overhagen	 * we are here => BBufferProducer::PrepareToConnect
655b2859abeSMarcus Overhagen	 *                BBufferConsumer::Connected
656b2859abeSMarcus Overhagen	 *                BBufferProducer::Connect
657b2859abeSMarcus Overhagen	 *
658b2859abeSMarcus Overhagen	 * At this point, the consumer's AcceptFormat() method has been called,
659b2859abeSMarcus Overhagen	 * and that node has potentially changed the proposed format. It may
660b2859abeSMarcus Overhagen	 * also have left wildcards in the format. PrepareToConnect()
661b2859abeSMarcus Overhagen	 * *must* fully specialize the format before returning!
662b2859abeSMarcus Overhagen	 */
663b2859abeSMarcus Overhagen
664b2859abeSMarcus Overhagen	TRACE("DVBMediaNode::PrepareToConnect: %s\n", SourceDefaultName(source));
665b2859abeSMarcus Overhagen
666b2859abeSMarcus Overhagen	#ifdef DEBUG
667b2859abeSMarcus Overhagen		TRACE("connecting format: ");
668b2859abeSMarcus Overhagen		PrintFormat(*format);
669b2859abeSMarcus Overhagen		TRACE("required format: ");
670b2859abeSMarcus Overhagen		switch (source.id) {
67138738909SColin Günther			case ID_RAW_VIDEO:
67238738909SColin Günther				PrintFormat(fRequiredFormatRawVideo);
67338738909SColin Günther				break;
67438738909SColin Günther
67538738909SColin Günther			case ID_RAW_AUDIO:
67638738909SColin Günther				PrintFormat(fRequiredFormatRawAudio);
67738738909SColin Günther				break;
67838738909SColin Günther
67938738909SColin Günther			case ID_ENC_VIDEO:
68038738909SColin Günther				PrintFormat(fRequiredFormatEncVideo);
68138738909SColin Günther				break;
68238738909SColin Günther
68338738909SColin Günther			case ID_ENC_AUDIO:
68438738909SColin Günther				PrintFormat(fRequiredFormatEncAudio);
68538738909SColin Günther				break;
68638738909SColin Günther
68738738909SColin Günther			case ID_TS:
68838738909SColin Günther				PrintFormat(fRequiredFormatTS);
68938738909SColin Günther				break;
690b2859abeSMarcus Overhagen		}
691b2859abeSMarcus Overhagen	#endif
692b2859abeSMarcus Overhagen
693b2859abeSMarcus Overhagen	// is the source valid?
694b2859abeSMarcus Overhagen	if (source.port != ControlPort())
695b2859abeSMarcus Overhagen		goto _bad_source;
696b2859abeSMarcus Overhagen
697b2859abeSMarcus Overhagen	// 1) check if the output is still available,
698b2859abeSMarcus Overhagen	// 2) specialize and verify the format
699b2859abeSMarcus Overhagen	switch (source.id) {
700b2859abeSMarcus Overhagen		case ID_RAW_VIDEO:
701b2859abeSMarcus Overhagen			if (fOutputRawVideo.destination != media_destination::null)
702b2859abeSMarcus Overhagen				goto _already_connected;
703b2859abeSMarcus Overhagen			SpecializeFormatRawVideo(&format->u.raw_video);
704b2859abeSMarcus Overhagen//			if (!format->Matches(&fRequiredFormatRawVideo))
705b2859abeSMarcus Overhagen//				goto _bad_format;
706b2859abeSMarcus Overhagen			if (!VerifyFormatRawVideo(format->u.raw_video))
707b2859abeSMarcus Overhagen				goto _bad_format;
708b2859abeSMarcus Overhagen			break;
709b2859abeSMarcus Overhagen
710b2859abeSMarcus Overhagen		case ID_RAW_AUDIO:
711b2859abeSMarcus Overhagen			if (fOutputRawAudio.destination != media_destination::null)
712b2859abeSMarcus Overhagen				goto _already_connected;
713b2859abeSMarcus Overhagen			SpecializeFormatRawAudio(&format->u.raw_audio);
714b2859abeSMarcus Overhagen			if (!format->Matches(&fRequiredFormatRawAudio))
715b2859abeSMarcus Overhagen				goto _bad_format;
716b2859abeSMarcus Overhagen			if (!VerifyFormatRawAudio(format->u.raw_audio))
717b2859abeSMarcus Overhagen				goto _bad_format;
718b2859abeSMarcus Overhagen			break;
719b2859abeSMarcus Overhagen
720b2859abeSMarcus Overhagen		case ID_ENC_VIDEO:
721b2859abeSMarcus Overhagen			if (fOutputEncVideo.destination != media_destination::null)
722b2859abeSMarcus Overhagen				goto _already_connected;
723b2859abeSMarcus Overhagen			SpecializeFormatEncVideo(&format->u.encoded_video);
724b2859abeSMarcus Overhagen			if (!format->Matches(&fRequiredFormatEncVideo))
725b2859abeSMarcus Overhagen				goto _bad_format;
726b2859abeSMarcus Overhagen			break;
727b2859abeSMarcus Overhagen
728b2859abeSMarcus Overhagen		case ID_ENC_AUDIO:
729b2859abeSMarcus Overhagen			if (fOutputEncAudio.destination != media_destination::null)
730b2859abeSMarcus Overhagen				goto _already_connected;
731b2859abeSMarcus Overhagen			SpecializeFormatEncAudio(&format->u.encoded_audio);
732b2859abeSMarcus Overhagen			if (!format->Matches(&fRequiredFormatRawVideo))
733b2859abeSMarcus Overhagen				goto _bad_format;
734b2859abeSMarcus Overhagen			break;
735b2859abeSMarcus Overhagen
736b2859abeSMarcus Overhagen		case ID_TS:
737b2859abeSMarcus Overhagen			if (fOutputTS.destination != media_destination::null)
738b2859abeSMarcus Overhagen				goto _already_connected;
739b2859abeSMarcus Overhagen			SpecializeFormatTS(&format->u.multistream);
740b2859abeSMarcus Overhagen			if (!format->Matches(&fRequiredFormatTS))
741b2859abeSMarcus Overhagen				goto _bad_format;
742b2859abeSMarcus Overhagen			break;
743b2859abeSMarcus Overhagen
744b2859abeSMarcus Overhagen		default:
745b2859abeSMarcus Overhagen			goto _bad_source;
746b2859abeSMarcus Overhagen	}
747b2859abeSMarcus Overhagen
748b2859abeSMarcus Overhagen	#ifdef DEBUG
749b2859abeSMarcus Overhagen		TRACE("final format: ");
750b2859abeSMarcus Overhagen		PrintFormat(*format);
751b2859abeSMarcus Overhagen	#endif
752b2859abeSMarcus Overhagen
753b2859abeSMarcus Overhagen	// reserve the connection by setting destination
754b2859abeSMarcus Overhagen	// set the output's format to the new format
755b2859abeSMarcus Overhagen	SetOutput(source, destination, *format);
756b2859abeSMarcus Overhagen
757b2859abeSMarcus Overhagen	// set source and suggest a name
758b2859abeSMarcus Overhagen	*out_source = source;
759b2859abeSMarcus Overhagen	strcpy(out_name, SourceDefaultName(source));
760b2859abeSMarcus Overhagen
761b2859abeSMarcus Overhagen	return B_OK;
762b2859abeSMarcus Overhagen
763b2859abeSMarcus Overhagen_bad_source:
764b2859abeSMarcus Overhagen	TRACE("Error: bad source!\n");
765b2859abeSMarcus Overhagen	return B_MEDIA_BAD_SOURCE;
766b2859abeSMarcus Overhagen
767b2859abeSMarcus Overhagen_bad_format:
768b2859abeSMarcus Overhagen	#ifdef DEBUG
769b2859abeSMarcus Overhagen		TRACE("Error, bad format: ");
770b2859abeSMarcus Overhagen		PrintFormat(*format);
771b2859abeSMarcus Overhagen	#endif
772b2859abeSMarcus Overhagen	return B_MEDIA_BAD_FORMAT;
773b2859abeSMarcus Overhagen
774b2859abeSMarcus Overhagen_already_connected:
775b2859abeSMarcus Overhagen	TRACE("Error: already connected!\n");
776b2859abeSMarcus Overhagen	return B_MEDIA_ALREADY_CONNECTED;
777b2859abeSMarcus Overhagen}
778b2859abeSMarcus Overhagen
779b2859abeSMarcus Overhagen
780b2859abeSMarcus Overhagenvoid
781b2859abeSMarcus OverhagenDVBMediaNode::Connect(status_t error, const media_source &source,
782b2859abeSMarcus Overhagen		const media_destination &destination, const media_format &format,
783b2859abeSMarcus Overhagen		char *io_name)
784b2859abeSMarcus Overhagen{
785b2859abeSMarcus Overhagen	/* The connection process:
786b2859abeSMarcus Overhagen	 *                BBufferProducer::FormatProposal
787b2859abeSMarcus Overhagen	 *                BBufferConsumer::AcceptFormat
788b2859abeSMarcus Overhagen	 *                BBufferProducer::PrepareToConnect
789b2859abeSMarcus Overhagen	 *                BBufferConsumer::Connected
790b2859abeSMarcus Overhagen	 * we are here => BBufferProducer::Connect
791b2859abeSMarcus Overhagen	 */
792b2859abeSMarcus Overhagen
793b2859abeSMarcus Overhagen	TRACE("DVBMediaNode::Connect: %s\n", SourceDefaultName(source));
794b2859abeSMarcus Overhagen
795b2859abeSMarcus Overhagen	if (error != B_OK) {
796b2859abeSMarcus Overhagen		TRACE("Error during connecting\n");
797b2859abeSMarcus Overhagen		// if an error occured, unreserve the connection
798b2859abeSMarcus Overhagen		ResetOutput(source);
799b2859abeSMarcus Overhagen		return;
800b2859abeSMarcus Overhagen	}
801b2859abeSMarcus Overhagen
802b2859abeSMarcus Overhagen	#ifdef DEBUG
803b2859abeSMarcus Overhagen		TRACE("connected format: ");
804b2859abeSMarcus Overhagen		PrintFormat(format);
805b2859abeSMarcus Overhagen	#endif
806b2859abeSMarcus Overhagen
807b2859abeSMarcus Overhagen	// Since the destination is allowed to be changed by the
808b2859abeSMarcus Overhagen	// consumer, the one we got in PrepareToConnect() is no
809b2859abeSMarcus Overhagen	// longer correct, and must be updated here.
810b2859abeSMarcus Overhagen	SetOutput(source, destination, format);
811b2859abeSMarcus Overhagen
812b2859abeSMarcus Overhagen	// Set output as connected
813b2859abeSMarcus Overhagen	switch (source.id) {
81438738909SColin Günther		case ID_RAW_VIDEO:
81538738909SColin Günther			fOutputEnabledRawVideo = true;
81638738909SColin Günther			break;
81738738909SColin Günther
81838738909SColin Günther		case ID_RAW_AUDIO:
81938738909SColin Günther			fOutputEnabledRawAudio = true;
82038738909SColin Günther			break;
82138738909SColin Günther
82238738909SColin Günther		case ID_ENC_VIDEO:
82338738909SColin Günther			fOutputEnabledEncVideo = true;
82438738909SColin Günther			break;
82538738909SColin Günther
82638738909SColin Günther		case ID_ENC_AUDIO:
82738738909SColin Günther			fOutputEnabledEncAudio = true;
82838738909SColin Günther			break;
82938738909SColin Günther
83038738909SColin Günther		case ID_TS:
83138738909SColin Günther			fOutputEnabledTS = true;
83238738909SColin Günther			break;
83338738909SColin Günther
83438738909SColin Günther		default:
83538738909SColin Günther			break;
836b2859abeSMarcus Overhagen	}
837b2859abeSMarcus Overhagen
838b2859abeSMarcus Overhagen	// if the connection has no name, we set it now
839b2859abeSMarcus Overhagen	if (strlen(io_name) == 0)
840b2859abeSMarcus Overhagen		strcpy(io_name, SourceDefaultName(source));
841b2859abeSMarcus Overhagen
842b2859abeSMarcus Overhagen	#ifdef DEBUG
843b2859abeSMarcus Overhagen		bigtime_t latency;
844b2859abeSMarcus Overhagen		media_node_id ts;
845b2859abeSMarcus Overhagen		if (B_OK != FindLatencyFor(destination, &latency, &ts))
846b2859abeSMarcus Overhagen			TRACE("FindLatencyFor failed\n");
847b2859abeSMarcus Overhagen		else
848b2859abeSMarcus Overhagen			TRACE("downstream latency %Ld\n", latency);
849b2859abeSMarcus Overhagen	#endif
850b2859abeSMarcus Overhagen}
851b2859abeSMarcus Overhagen
852b2859abeSMarcus Overhagen
853b2859abeSMarcus Overhagenvoid
854b2859abeSMarcus OverhagenDVBMediaNode::Disconnect(const media_source &source,
855b2859abeSMarcus Overhagen		const media_destination &destination)
856b2859abeSMarcus Overhagen{
857b2859abeSMarcus Overhagen	TRACE("DVBMediaNode::Disconnect: %s\n", SourceDefaultName(source));
858b2859abeSMarcus Overhagen
859b2859abeSMarcus Overhagen	// unreserve the connection
860b2859abeSMarcus Overhagen	ResetOutput(source);
861b2859abeSMarcus Overhagen
862b2859abeSMarcus Overhagen	// Set output to disconnected
863b2859abeSMarcus Overhagen	switch (source.id) {
86438738909SColin Günther		case ID_RAW_VIDEO:
86538738909SColin Günther			fOutputEnabledRawVideo = false;
86638738909SColin Günther			break;
86738738909SColin Günther
86838738909SColin Günther		case ID_RAW_AUDIO:
86938738909SColin Günther			fOutputEnabledRawAudio = false;
87038738909SColin Günther			break;
87138738909SColin Günther
87238738909SColin Günther		case ID_ENC_VIDEO:
87338738909SColin Günther			fOutputEnabledEncVideo = false;
87438738909SColin Günther			break;
87538738909SColin Günther
87638738909SColin Günther		case ID_ENC_AUDIO:
87738738909SColin Günther			fOutputEnabledEncAudio = false;
87838738909SColin Günther			break;
87938738909SColin Günther
88038738909SColin Günther		case ID_TS:
88138738909SColin Günther			fOutputEnabledTS = false;
88238738909SColin Günther			break;
88338738909SColin Günther
88438738909SColin Günther		default:
88538738909SColin Günther			break;
886b2859abeSMarcus Overhagen	}
887b2859abeSMarcus Overhagen}
888b2859abeSMarcus Overhagen
889b2859abeSMarcus Overhagen
890b2859abeSMarcus Overhagenvoid
891b2859abeSMarcus OverhagenDVBMediaNode::LateNoticeReceived(const media_source &source,
892b2859abeSMarcus Overhagen		bigtime_t how_much, bigtime_t performance_time)
893b2859abeSMarcus Overhagen{
89438738909SColin Günther	TRACE("DVBMediaNode::LateNoticeReceived %Ld late at %Ld\n", how_much,
89538738909SColin Günther		performance_time);
896b2859abeSMarcus Overhagen}
897b2859abeSMarcus Overhagen
898b2859abeSMarcus Overhagen
899b2859abeSMarcus Overhagenvoid
900b2859abeSMarcus OverhagenDVBMediaNode::EnableOutput(const media_source &source, bool enabled,
901b2859abeSMarcus Overhagen		int32 *_deprecated_)
902b2859abeSMarcus Overhagen{
90338738909SColin Günther	TRACE("DVBMediaNode::EnableOutput id = %ld, enabled = %d\n", source.id,
90438738909SColin Günther		enabled);
905b2859abeSMarcus Overhagen	/* not used yet
906b2859abeSMarcus Overhagen	switch (source.id) {
907b2859abeSMarcus Overhagen		case ID_RAW_VIDEO:	fOutputEnabledRawVideo = enabled; break;
908b2859abeSMarcus Overhagen		case ID_RAW_AUDIO:	fOutputEnabledRawAudio = enabled; break;
909b2859abeSMarcus Overhagen		case ID_ENC_VIDEO:	fOutputEnabledEncVideo = enabled; break;
910b2859abeSMarcus Overhagen		case ID_ENC_AUDIO:	fOutputEnabledEncAudio = enabled; break;
911b2859abeSMarcus Overhagen		case ID_TS:			fOutputEnabledTS = enabled; break;
912b2859abeSMarcus Overhagen		default:			break;
913b2859abeSMarcus Overhagen	}
914b2859abeSMarcus Overhagen	*/
915b2859abeSMarcus Overhagen}
916b2859abeSMarcus Overhagen
917b2859abeSMarcus Overhagen
918b2859abeSMarcus Overhagenstatus_t
919b2859abeSMarcus OverhagenDVBMediaNode::SetPlayRate(int32 numer, int32 denom)
920b2859abeSMarcus Overhagen{
921b2859abeSMarcus Overhagen
922b2859abeSMarcus Overhagen	return B_ERROR;
923b2859abeSMarcus Overhagen}
924b2859abeSMarcus Overhagen
925b2859abeSMarcus Overhagen
926b2859abeSMarcus Overhagenvoid
927b2859abeSMarcus OverhagenDVBMediaNode::AdditionalBufferRequested(const media_source &source,
928b2859abeSMarcus Overhagen		media_buffer_id prev_buffer, bigtime_t prev_time,
929b2859abeSMarcus Overhagen		const media_seek_tag *prev_tag)
930b2859abeSMarcus Overhagen{
93138738909SColin Günther	TRACE("DVBMediaNode::AdditionalBufferRequested: %s\n",
93238738909SColin Günther		SourceDefaultName(source));
933b2859abeSMarcus Overhagen}
934b2859abeSMarcus Overhagen
935b2859abeSMarcus Overhagen
936b2859abeSMarcus Overhagenvoid
937b2859abeSMarcus OverhagenDVBMediaNode::LatencyChanged(const media_source &source,
938b2859abeSMarcus Overhagen		const media_destination &destination, bigtime_t new_latency,
939b2859abeSMarcus Overhagen		uint32 flags)
940b2859abeSMarcus Overhagen{
941b2859abeSMarcus Overhagen	TRACE("DVBMediaNode::LatencyChanged to %Ld\n", new_latency);
942b2859abeSMarcus Overhagen}
943b2859abeSMarcus Overhagen
944b2859abeSMarcus Overhagen/* DVBMediaNode */
945b2859abeSMarcus Overhagen
946b2859abeSMarcus Overhagen
947b2859abeSMarcus Overhagenvoid
948b2859abeSMarcus OverhagenDVBMediaNode::HandleTimeWarp(bigtime_t performance_time)
949b2859abeSMarcus Overhagen{
950b2859abeSMarcus Overhagen	TRACE("DVBMediaNode::HandleTimeWarp at %Ld\n", performance_time);
951b2859abeSMarcus Overhagen}
952b2859abeSMarcus Overhagen
953b2859abeSMarcus Overhagen
954b2859abeSMarcus Overhagenvoid
955b2859abeSMarcus OverhagenDVBMediaNode::HandleSeek(bigtime_t performance_time)
956b2859abeSMarcus Overhagen{
957b2859abeSMarcus Overhagen	TRACE("DVBMediaNode::HandleSeek at %Ld\n", performance_time);
958b2859abeSMarcus Overhagen}
959b2859abeSMarcus Overhagen
960b2859abeSMarcus Overhagen
961b2859abeSMarcus Overhagenvoid
962b2859abeSMarcus OverhagenDVBMediaNode::InitDefaultFormats()
963b2859abeSMarcus Overhagen{
964b2859abeSMarcus Overhagen	// 720 * 576
965b2859abeSMarcus Overhagen	fDefaultFormatRawVideo.type = B_MEDIA_RAW_VIDEO;
966b2859abeSMarcus Overhagen	fDefaultFormatRawVideo.u.raw_video.display.format = B_RGB32;
967b2859abeSMarcus Overhagen	fDefaultFormatRawVideo.u.raw_video.display.line_width = 720;
968b2859abeSMarcus Overhagen	fDefaultFormatRawVideo.u.raw_video.display.line_count = 576;
96938738909SColin Günther	fDefaultFormatRawVideo.u.raw_video.last_active
97038738909SColin Günther		= fDefaultFormatRawVideo.u.raw_video.display.line_count - 1;
97138738909SColin Günther	fDefaultFormatRawVideo.u.raw_video.display.bytes_per_row
97238738909SColin Günther		= fDefaultFormatRawVideo.u.raw_video.display.line_width * 4;
97338738909SColin Günther	fDefaultFormatRawVideo.u.raw_video.field_rate = 0;
97438738909SColin Günther		// wildcard
975b2859abeSMarcus Overhagen	fDefaultFormatRawVideo.u.raw_video.interlace = 1;
976b2859abeSMarcus Overhagen	fDefaultFormatRawVideo.u.raw_video.first_active = 0;
977b2859abeSMarcus Overhagen	fDefaultFormatRawVideo.u.raw_video.orientation = B_VIDEO_TOP_LEFT_RIGHT;
978b2859abeSMarcus Overhagen	fDefaultFormatRawVideo.u.raw_video.pixel_width_aspect = 1;
979b2859abeSMarcus Overhagen	fDefaultFormatRawVideo.u.raw_video.pixel_height_aspect = 1;
980b2859abeSMarcus Overhagen	fDefaultFormatRawVideo.u.raw_video.display.pixel_offset = 0;
981b2859abeSMarcus Overhagen	fDefaultFormatRawVideo.u.raw_video.display.line_offset = 0;
982b2859abeSMarcus Overhagen	fDefaultFormatRawVideo.u.raw_video.display.flags = 0;
983b2859abeSMarcus Overhagen
984b2859abeSMarcus Overhagen	fDefaultFormatRawAudio.type = B_MEDIA_RAW_AUDIO;
985b2859abeSMarcus Overhagen	fDefaultFormatRawAudio.u.raw_audio.frame_rate = 48000;
986b2859abeSMarcus Overhagen	fDefaultFormatRawAudio.u.raw_audio.channel_count = 2;
987fc925276SMarcus Overhagen//  XXX broken in Haiku...
988fc925276SMarcus Overhagen//	fDefaultFormatRawAudio.u.raw_audio.format = 0; // wildcard
98938738909SColin Günther	fDefaultFormatRawAudio.u.raw_audio.format
99038738909SColin Günther		= media_raw_audio_format::B_AUDIO_SHORT;
991b2859abeSMarcus Overhagen//  when set to 0, haiku mixer has problems when diung a format change
992b2859abeSMarcus Overhagen//  set to short and debug the buffer_size problem first!
993b2859abeSMarcus Overhagen	fDefaultFormatRawAudio.u.raw_audio.byte_order = B_MEDIA_HOST_ENDIAN;
994fc925276SMarcus Overhagen//	fDefaultFormatRawAudio.u.raw_audio.buffer_size = 0; // wildcard
995b2859abeSMarcus Overhagen//	fDefaultFormatRawAudio.u.raw_audio.buffer_size = 0x1200;
996b2859abeSMarcus Overhagen//	fDefaultFormatRawAudio.u.raw_audio.buffer_size = 0x1000;
997fc925276SMarcus Overhagen	fDefaultFormatRawAudio.u.raw_audio.buffer_size = 32768;
998b2859abeSMarcus Overhagen//	fDefaultFormatRawAudio.u.raw_audio.buffer_size = 333 * 8;
999b2859abeSMarcus Overhagen//	fDefaultFormatRawAudio.u.raw_audio.buffer_size = 512;
1000b2859abeSMarcus Overhagen//  when set to anything different from 32768 haiku mixer has problems
1001b2859abeSMarcus Overhagen
1002b2859abeSMarcus Overhagen	fDefaultFormatEncVideo.type = B_MEDIA_ENCODED_VIDEO;
1003b2859abeSMarcus Overhagen	fDefaultFormatEncAudio.type = B_MEDIA_ENCODED_AUDIO;
1004b2859abeSMarcus Overhagen	fDefaultFormatTS.type = B_MEDIA_MULTISTREAM;
1005b2859abeSMarcus Overhagen}
1006b2859abeSMarcus Overhagen
1007b2859abeSMarcus Overhagen
1008b2859abeSMarcus Overhagenbool
1009b2859abeSMarcus OverhagenDVBMediaNode::VerifyFormatRawVideo(const media_raw_video_format &format)
1010b2859abeSMarcus Overhagen{
1011b2859abeSMarcus Overhagen	if (format.display.format != 0 &&
1012b2859abeSMarcus Overhagen		format.display.format != B_RGB32 &&
1013b2859abeSMarcus Overhagen		format.display.format != B_YCbCr422)
1014b2859abeSMarcus Overhagen		return false;
1015b2859abeSMarcus Overhagen
1016b2859abeSMarcus Overhagen	return true;
1017b2859abeSMarcus Overhagen}
1018b2859abeSMarcus Overhagen
1019b2859abeSMarcus Overhagen
1020b2859abeSMarcus Overhagenbool
1021b2859abeSMarcus OverhagenDVBMediaNode::VerifyFormatRawAudio(const media_multi_audio_format &format)
1022b2859abeSMarcus Overhagen{
1023b2859abeSMarcus Overhagen	if (format.format != 0 &&
1024b2859abeSMarcus Overhagen		format.format != media_raw_audio_format::B_AUDIO_FLOAT &&
1025b2859abeSMarcus Overhagen		format.format != media_raw_audio_format::B_AUDIO_SHORT)
1026b2859abeSMarcus Overhagen		return false;
1027b2859abeSMarcus Overhagen
1028b2859abeSMarcus Overhagen	return true;
1029b2859abeSMarcus Overhagen}
1030b2859abeSMarcus Overhagen
1031b2859abeSMarcus Overhagen
1032b2859abeSMarcus Overhagenvoid
1033b2859abeSMarcus OverhagenDVBMediaNode::SpecializeFormatRawVideo(media_raw_video_format *format)
1034b2859abeSMarcus Overhagen{
1035b2859abeSMarcus Overhagen	// Here we need to specialize *all* remaining wildcard
1036b2859abeSMarcus Overhagen	// fields that the consumer didn't set
1037b2859abeSMarcus Overhagen	if (format->field_rate == 0.0)
1038b2859abeSMarcus Overhagen		format->field_rate = 25;
1039b2859abeSMarcus Overhagen
1040b2859abeSMarcus Overhagen	// XXX a lot is missing here...
1041b2859abeSMarcus Overhagen}
1042b2859abeSMarcus Overhagen
1043b2859abeSMarcus Overhagen
1044b2859abeSMarcus Overhagenvoid
1045b2859abeSMarcus OverhagenDVBMediaNode::SpecializeFormatRawAudio(media_multi_audio_format *format)
1046b2859abeSMarcus Overhagen{
1047b2859abeSMarcus Overhagen	// Here we need to specialize *all* remaining wildcard
1048b2859abeSMarcus Overhagen	// fields that the consumer didn't set
1049b2859abeSMarcus Overhagen	if (format->format == 0)
1050b2859abeSMarcus Overhagen		format->format = media_raw_audio_format::B_AUDIO_SHORT;
1051b2859abeSMarcus Overhagen
1052b2859abeSMarcus Overhagen	if (format->buffer_size == 0)
1053b2859abeSMarcus Overhagen		format->buffer_size = 333 * 8;
1054b2859abeSMarcus Overhagen
1055b2859abeSMarcus Overhagen	// XXX a lot is missing here...
1056b2859abeSMarcus Overhagen}
1057b2859abeSMarcus Overhagen
1058b2859abeSMarcus Overhagen
1059b2859abeSMarcus Overhagenvoid
1060